Beego ya no es Go

Cualquier bombo es muy divertido cuando lo miras desde un lado. Menos divertido cuando te involucras directamente en él.

Hype Go cayó en algún lugar en 2014, cuando los autores de aplicaciones que tenían 1000 RPM (solicitudes por minuto) de repente decidieron que necesitaban urgentemente la concurrencia, porque su 1000 RPM estaba a punto de convertirse en 1000 RPS (que tampoco es tanto, de hecho)

El resultado de la exageración fue que muchas personas que se acostumbraron a la arquitectura MVC de la aplicación se unieron a Go, ya sea Spring, Django o Ruby on Rails. Y esta arquitectura, como un búho en un globo terráqueo, comenzaron a tirar de Go. Entonces aparecieron cadavres como Beego y Revel . Revel murió de manera segura, aunque todavía están tratando de sacarlo. Pero quiero hablar de Beego por separado.

Richard Eng hizo una contribución significativa a la promoción de Beego entre las masas con su serie de artículos "A word the Beegoist" . Prácticamente el "Evangelio de Ricardo". Irónicamente, a pesar del hecho de que Richard está promoviendo frenéticamente a Go, él mismo no escribe sobre eso.

A su vez, trabajé con Go, y lo que es peor, con Beego, trabajé mucho. Y puedo decir que esta claramente no es la forma en que debería ir el desarrollo en Go.

Veamos algunos aspectos básicos de Beego y por qué contradicen varias prácticas recomendadas en Go y en la industria en general.

Estructura de carpetas


Robert C. Martin, mejor conocido como tío Bob , ha expresado repetidamente la idea de que la estructura de una aplicación debe transmitir su esencia. Le gusta mucho dar un ejemplo con una catedral, que se puede ver desde arriba, y comprender de inmediato que se trata de una catedral.

Robert ha criticado repetidamente a Ruby on Rails por su estructura de carpetas: controladores, modelos, vistas, eso es todo. El problema con este enfoque es que la aplicación de calcetines más vendida se verá exactamente como una aplicación para ordenar alimentos. Y para comprender la esencia de la aplicación, tendrá que subir a la carpeta de algunos modelos y ver con qué tipo de entidades terminamos.

Es este comportamiento enfermo de Beego el que se replica. Mientras que el mismo Spring se ha movido hacia el diseño impulsado por dominio y la esencia de la estructura de carpetas, Beego impone el uso de una estructura que ya se ha vuelto antipatrón.

Pero el problema es aún más grave. Para Go, no hay separación entre la estructura de la carpeta y la estructura del paquete. Por lo tanto, en Beego y UsersController y OrdersController estarán bajo un paquete: controladores. Y si tiene dos tipos de controladores, los que sirven a la interfaz de usuario y los que se utilizan para la API, además, ¿es habitual versionarlos en una sociedad decente? Entonces prepárate para fenómenos como apiv1.

ORM


Por extraño que parezca, Beego, al ser un clon fracasado de Ruby on Rails, no utiliza el patrón ActiveRecord. Su ORM es una vista extremadamente extraña. Si para operaciones completamente básicas, como leer una línea / escribir una línea, sigue siendo adecuada, entonces, por ejemplo, parece una muestra simple (en adelante, los ejemplos se toman directamente de la documentación):

qs.Filter("profile__age__gte", 18) // WHERE profile.age >= 18 

Pero el principal problema con Beego ORM ni siquiera es que necesite tratar con el lenguaje propietario, sino que utiliza todas las peores prácticas de Go, ya sean efectos secundarios de importación:

 import ( _ "github.com/go-sql-driver/mysql" _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" ) 

O registrar modelos en init ():

 func init(){ orm.RegisterModel(new(User)) } 

Hazte un favor, incluso si aún decides por alguna razón inexplicable trabajar con Beego, no uses Beego ORM. Si tu vida sin ORM no es agradable (¿y qué estás haciendo en el mundo de Go, querido?), Usa GORM . Al menos es compatible. De lo contrario, "database / sql" lo ayudará.

Herramienta de abeja


La herramienta de línea de comandos, que simplemente se llama Bee , se copia de Ruby on Rails. Pero solo si en el mundo de RoR había rieles y rastrillos, entonces la abeja es una basura para todo. Él y la aplicación MVC para 'boostrap', y ejecutan la migración, y se iniciará el observador de archivos. Este último es otro problema. Después de todo, ¿cuál es una de las principales ventajas de Go? Lo que comienza localmente es lo más cercano posible a lo que comienza en la producción. Si no usas abeja, por supuesto.

Enrutamiento automático


Go es un lenguaje fuertemente tipado que no admite genéricos ni anotaciones. ¿Cómo moldear un marco MVC en esto? Al leer comentarios y generar archivos, por supuesto.

Se parece a esto:

 // @Param body body models.Object true "The object content" // @Success 200 {string} models.Object.Id // @Failure 403 body is empty // @router / [post] func (this *ObjectController) Post() { var ob models.Object json.Unmarshal(this.Ctx.Input.RequestBody, &ob) objectid := models.AddOne(ob) this.Data["json"] = map[string]string{"ObjectId": objectid} this.ServeJson() } 

La evidencia, como puede ver, es cero. La función Post () no recibe ni devuelve nada en absoluto. http.Request? No, no escuchado.

Bueno, ¿cómo funciona todo el enrutamiento? Cuando inicia la notoria abeja, se genera otro archivo, commentsRouter_controllers.go, que contiene un ejemplo de un código tan maravilloso:

 func init() { beego.GlobalControllerRouter["github.com/../../controllers:ObjectController"] = append(beego.GlobalControllerRouter["github.com/../../controllers:ObjectController"], beego.ControllerComments{ Method: "Post", Router: `/`, AllowHTTPMethods: []string{"post"}, MethodParams: param.Make(), Filters: nil, Params: nil}) ... } 

Vea, no olvide regenerar y 'confirmar' este archivo después de cada cambio. Hasta hace poco, la situación era aún más triste, y durante las pruebas este archivo se generó automáticamente, por lo que ya aprendió sobre los problemas en la producción. Parece que en versiones recientes se ha solucionado este extraño comportamiento.

Prueba de componentes


Y así llegamos al tema de las pruebas. Go, a diferencia de la mayoría de los otros lenguajes de programación, viene con un marco de prueba listo para usar. En general, la filosofía de Go es que la prueba debe estar al lado del archivo de prueba. Pero estamos en el mundo MVC, escupe la filosofía Go, ¿verdad? Por lo tanto, tenga la amabilidad de colocar todas sus pruebas en / test daddy, como DHH nos legó.

Y esto no es tan sencillo, porque, recuerdo, en la carpeta Go package ==. Y si la prueba ubicada en el mismo paquete puede llamar al método privado, entonces la prueba ubicada en otro paquete ya no está allí.

Pero bueno, todo estaría limitado a la estructura de carpetas. El código de Beego es, en principio, muy difícil de probar, porque todo lo que contiene es un efecto secundario.

Así es como Beego consulta los enrutadores:

 import ( _ "github.com/../../routers" ) 

La misma historia con middlewares y con controladores que mencioné anteriormente.

La documentación


Es como un arquitecto de software para mí en un pastel. La documentación de BeeGo es tan buena como su chino. No, los comentarios en chino dentro del código en los últimos dos años se han eliminado.

Ahora en chino solo hay unas pocas solicitudes de extracción:

imagen

Y especialmente en temas:



En lugar de una conclusión


Si tiene un equipo de escritores de código Ruby / PHP / Python y desea traducirlos urgentemente a Go, lo peor que puede hacer por ellos es hacer que cambien al marco MVC en Go. MVC en su conjunto es un patrón arquitectónico regular, y en Go generalmente está fuera de lugar. O, si está absolutamente seguro de que nada más que Go lo salvará, permítales volver a aprender y escribir de la forma en que se acepta en Go, de la manera más simple y explícita posible. O, tal vez lo sepan mejor, ¿con qué herramienta resolver sus tareas?

Source: https://habr.com/ru/post/444022/


All Articles