paint-brush
Creación de un servicio de API RESTful en Go sin tener un patrón repetitivopor@ichebykin
1,160 lecturas
1,160 lecturas

Creación de un servicio de API RESTful en Go sin tener un patrón repetitivo

por Mify6m2023/03/06
Read on Terminal Reader

Demasiado Largo; Para Leer

Hemos estado escribiendo servicios durante bastante tiempo y, la mayoría de las veces, solo querrá omitir todo este tedioso proceso de unir cosas y simplemente escribir código útil, por lo que creamos Mify, un generador de código repetitivo de infraestructura de código abierto. En este tutorial, mostraremos cómo crear un servicio simple usando Mify con un ejemplo clásico: una aplicación de tareas pendientes.
featured image - Creación de un servicio de API RESTful en Go sin tener un patrón repetitivo
Mify HackerNoon profile picture



Hay muchos materiales sobre cómo escribir servicios, donde primero debe elegir algún marco para usar, luego viene el cableado de controladores, configuraciones, registros, almacenamiento, etc., sin mencionar la implementación de ese servicio en alguna parte. Hemos estado escribiendo servicios durante bastante tiempo y, la mayoría de las veces, solo querrá omitir todo este tedioso proceso de unir cosas y simplemente escribir un código útil.


Es por eso que creamos una herramienta, llamada Mify: es un generador repetitivo de infraestructura de código abierto, que lo ayudaría a crear un servicio, tomando las mejores prácticas utilizadas hasta la fecha. Entonces, en este tutorial, mostraremos cómo crear un servicio simple usando Mify con un ejemplo clásico: una aplicación de tareas pendientes.

requisitos previos

Antes de comenzar este tutorial, aquí está el enlace al ejemplo completo: https://github.com/mify-io/todo-app-example

Creando proyecto

Después de instalar Mify, para iniciar el proyecto necesitas crear el espacio de trabajo:

 $ mify init todo-app $ cd todo-app


Después de ingresar al nuevo espacio de trabajo, ejecute:

 $ mify add service todo-backend


Ahora, esto creará una plantilla Go para su backend de tareas pendientes. Aquí hay un árbol simplificado del espacio de trabajo con todos los archivos generados:

 . ├── go-services │ ├── cmd │ │ ├── dev-runner │ │ │ └── main.go │ │ └── todo-backend │ │ ├── Dockerfile │ │ └── main.go │ ├── go.mod │ ├── go.sum │ └── internal │ ├── pkg │ │ └── generated │ │ ├── configs │ │ │ └── ... │ │ ├── consul │ │ │ └── ... │ │ ├── logs │ │ │ └── ... │ │ └── metrics │ │ └── ... │ └── todo-backend │ ├── app │ │ ├── request_extra.go │ │ ├── router │ │ │ └── router.go │ │ └── service_extra.go │ └── generated │ ├── api | | └── ... │ ├── app │ │ └── ... │ ├── apputil │ │ └── ... │ └── core │ └── ... ├── schemas │ └── todo-backend │ ├── api │ │ └── api.yaml │ └── service.mify.yaml └── workspace.mify.yaml


Mify sigue vagamente uno de los diseños comunes de Go, que es adecuado para múltiples servicios en un repositorio. En internal/pkg/generated hay bibliotecas comunes para configuraciones, registros y métricas que se pueden reutilizar para múltiples servicios. Su directorio de acceso al servicio está en internal/todo-backend .

En este punto, este servicio es bastante básico, por lo que debemos agregarle una API.

Definición de API

Puede encontrar el esquema de OpenAPI para el backend de tareas pendientes en el archivo schemas/todo-backend/api/api.yaml . El directorio de esquemas en la raíz del espacio de trabajo es un lugar donde se almacenan todas las configuraciones de servicio relacionadas con Mify.


Vamos a crear una API CRUD simple para su backend de tareas pendientes:

  • POST /todos para agregar nuevas notas de tareas pendientes.
  • PUT,GET,DELETE /todos/{id} para actualizarlos, recuperarlos y eliminarlos.

Así es como se vería su esquema OpenAPI para esta API:

https://gist.github.com/chebykinn/5dc7b30a2a57a1ab4584895131295e1f

Reemplace el esquema anterior con este y ejecute mify generate . Puede ejecutarlo cada vez que actualice el esquema y regenerará todas las cosas modificadas.

Construcción y Pruebas

 $ cd go-services $ go mod tidy $ go run ./cmd/todo-backend


Debería ver registros de inicio como ese:

Puede ver el puerto de servicio al starting api server , copiarlo en Postman e intentar llamar a algún controlador de API:

Puede ver que el controlador no devolvió nada, lo que se esperaba porque, como sugiere el error, aún no está implementado.

Adición de modelos y almacenamiento simulado

Primero, necesitamos crear un modelo para la nota de tareas, lo pondremos en el paquete domain

en go-services/internal/todo-backend/domain/todo.go :

Este también es un buen lugar para definir la interfaz de almacenamiento, que es útil para desacoplar la lógica de persistencia de la aplicación. En este tutorial, usaremos almacenamiento simulado en la memoria, pero Mify también es compatible con Postgres, que podemos agregar más adelante en un artículo de seguimiento. Pongamos almacenamiento en go-services/internal/todo-backend/storage/todo_mem.go:

Eso es todo por lógica, solo necesitamos agregarlo a los controladores.

Implementación de controladores

go-services/internal/todo-backend/handlers/todos/service.go para el método POST, y

go-services/internal/todo-backend/handlers/todos/id/service.go para otros.

Aquí hay un ejemplo de un código auxiliar del método POST:

Ahora, implementemos todos los controladores.

go-services/internal/todo-backend/handlers/todos/service.go :

No olvides actualizar las importaciones:

 import ( "net/http" "strconv" "example.com/namespace/todo-app/go-services/internal/todo-backend/domain" "example.com/namespace/todo-app/go-services/internal/todo-backend/generated/api" "example.com/namespace/todo-app/go-services/internal/todo-backend/generated/apputil" "example.com/namespace/todo-app/go-services/internal/todo-backend/generated/core" "example.com/namespace/todo-app/go-services/internal/todo-backend/handlers" )


go-services/internal/todo-backend/handlers/todos/id/service.go :

Y aquí también hay importaciones para ellos:

 import ( "errors" "fmt" "net/http" "strconv" "example.com/namespace/todo-app/go-services/internal/todo-backend/domain" "example.com/namespace/todo-app/go-services/internal/todo-backend/generated/api" "example.com/namespace/todo-app/go-services/internal/todo-backend/generated/apputil" "example.com/namespace/todo-app/go-services/internal/todo-backend/generated/core" "example.com/namespace/todo-app/go-services/internal/todo-backend/handlers" "example.com/namespace/todo-app/go-services/internal/todo-backend/storage" )


La lógica del controlador es bastante simple, solo estamos convirtiendo los modelos OpenAPI generados a nuestra aplicación uno y viceversa, y para evitar la duplicación en el código, aquí hay una ayuda para crear una respuesta de TodoNode, que se usa en estas implementaciones:

go-services/internal/todo-backend/handlers/common.go :

Probando de nuevo

Primero, podemos agregar una nueva nota de tareas pendientes con una solicitud POST:

Compruebe si se agrega con una solicitud GET:

Actualízalo con una solicitud PUT:

Bórralo:

Y ejecute GET una vez más para verificar si se eliminó:

Que sigue

  • Almacenamiento persistente, como Postgres,

  • Configuración,

  • software intermedio de autenticación,

  • Implementación en la nube.


La mayoría de estas cosas están cubiertas en nuestros documentos, así que échales un vistazo: https://mify.io/docs , pero mantente atento a los próximos artículos.


También publicado aquí