paint-brush
Construindo um serviço de API RESTful em Go sem ter um clichê repetitivopor@ichebykin
1,160 leituras
1,160 leituras

Construindo um serviço de API RESTful em Go sem ter um clichê repetitivo

por Mify6m2023/03/06
Read on Terminal Reader

Muito longo; Para ler

Escrevemos serviços há algum tempo e, na maioria das vezes, você deseja apenas pular todo esse processo tedioso de colar coisas e apenas escrever códigos úteis, então criamos o Mify - um gerador clichê de infraestrutura de código aberto. Neste tutorial, mostraremos como criar um serviço simples usando o Mify com um exemplo clássico — um app de tarefas.
featured image - Construindo um serviço de API RESTful em Go sem ter um clichê repetitivo
Mify HackerNoon profile picture



Existem muitos materiais sobre como escrever serviços, onde primeiro você precisa escolher algum framework para usar, depois vem a fiação de manipuladores, configurações, logs, armazenamento, etc, sem falar na implantação desse serviço em algum lugar. Estamos escrevendo serviços há algum tempo e, na maioria das vezes, você deseja apenas pular todo esse processo tedioso de colar coisas e apenas escrever algum código útil.


É por isso que criamos uma ferramenta, chamada Mify — é um gerador padrão de infraestrutura de código aberto, que ajudaria você a construir um serviço, adotando as melhores práticas usadas até o momento. Portanto, neste tutorial, mostraremos como criar um serviço simples usando o Mify com um exemplo clássico — um aplicativo de tarefas.

Pré-requisitos

Antes de iniciar este tutorial, aqui está o link para o exemplo completo: https://github.com/mify-io/todo-app-example

Criando Projeto

Depois de instalar o Mify, para iniciar o projeto você precisa criar o espaço de trabalho:

 $ mify init todo-app $ cd todo-app


Depois de entrar no novo espaço de trabalho, execute:

 $ mify add service todo-backend


Agora, isso criará um modelo Go para o seu back-end de tarefas. Aqui está uma árvore simplificada do espaço de trabalho com todos os arquivos gerados:

 . ├── 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


O Mify segue vagamente um dos layouts Go comuns, que é adequado para vários serviços em um repositório. Em internal/pkg/generated existem bibliotecas comuns para configurações, logs e métricas que podem ser reutilizadas para vários serviços. O diretório go-to do seu serviço está em internal/todo-backend .

Neste ponto, este serviço está bastante vazio, então precisamos adicionar uma API a ele.

API de definição

Você pode encontrar o esquema OpenAPI para o todo-backend no arquivo schemas/todo-backend/api/api.yaml . O diretório Schemas na raiz do espaço de trabalho é um local onde todas as configurações de serviço relacionadas ao Mify são armazenadas.


Vamos criar uma API CRUD simples para seu back-end de tarefas:

  • POST /todos para adicionar novas notas de tarefas.
  • PUT,GET,DELETE /todos/{id} para atualizá-los, recuperá-los e excluí-los.

Veja como seu esquema OpenAPI ficaria para esta API:

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

Substitua o esquema anterior por este e execute mify generate . Você pode executá-lo sempre que atualizar o esquema e ele regenerará todas as coisas alteradas.

Construindo e Testando

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


Você deve ver logs de inicialização como este:

Você pode ver a porta de serviço ao starting api server , copiá-la para o Postman e tentar chamar algum manipulador de API:

Você pode ver que o manipulador não retornou nada, o que é esperado porque, como o erro sugere, ele ainda não foi implementado.

Adicionando modelos e armazenamento simulado

Primeiro, precisamos criar um modelo para a nota de tarefas, vamos colocá-lo no pacote domain

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

Este também é um bom lugar para definir a interface para armazenamento, o que é útil para desacoplar a lógica de persistência do aplicativo. Neste tutorial, usaremos armazenamento simulado, na memória, mas o Mify também oferece suporte ao Postgres, que podemos adicionar posteriormente em um artigo subsequente. Vamos colocar o armazenamento em go-services/internal/todo-backend/storage/todo_mem.go:

Isso é tudo para a lógica, só precisamos adicioná-lo aos manipuladores.

Implementando Manipuladores

go-services/internal/todo-backend/handlers/todos/service.go para o método POST e

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

Aqui está um exemplo de um stub do método POST:

Agora, vamos implementar todos os manipuladores.

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

Não se esqueça de atualizar as importações:

 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 :

E aqui estão as importações para eles também:

 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" )


A lógica do manipulador é bem simples, estamos apenas convertendo os modelos OpenAPI gerados em nosso aplicativo e vice-versa, e para evitar a duplicação no código, aqui está um auxiliar para criar uma resposta TodoNode, que é usada nestas implementações:

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

Testando novamente

Primeiro, podemos adicionar uma nova nota de tarefa com uma solicitação POST:

Verifique se ele é adicionado com uma solicitação GET:

Atualize-o com uma solicitação PUT:

Delete isso:

E execute GET mais uma vez para verificar se foi deletado:

Qual é o próximo

  • Armazenamento persistente, como Postgres,

  • Configuração,

  • Middleware de autenticação,

  • Implantação na nuvem.


A maioria dessas coisas é abordada em nossos documentos, então confira: https://mify.io/docs , mas fique atento aos próximos artigos.


Também publicado aqui