Criando serviços
Para construir um novo serviço, algumas regras e padrões precisam ser seguidas conforme a sua categoria.
Contudo, para todas as categorias, um serviço deve possuir pelo menos os seguintes arquivos em seu diretório:
service
\_go.mod
\_go.sum
\_service.toml
\_main.go
Os arquivos go.mod e go.sum são da própria linguagem go, para controle de nome do módulo e suas dependências.
O arquivo service.toml contém informações pertinentes ao serviço, como nome, versão, linguagem de programação utilizada por ele, variáveis de ambiente, etc. Este arquivo é obrigatório para a inicialização correta de um serviço, além de sofrer validações durante a execução do pipeline de CI/CD em um merge request.
O arquivo main.go deve conter todo código responsável pela inicialização do serviço, seja utilizando a API correta conforme a sua categoria, bem como inicializando componentes externos particulares para o funcionamento do próprio serviço, como a inicialização de um recurso externo, por exemplo.
Um serviço pode também possuir outros arquivos fonte. Contudo, estes variam conforme a sua categoria.
Adicionalmente, para os serviços do Somatech, todo serviço também precisa possuir os seguintes arquivos:
Um arquivo README.md é um arquivo texto, com sintaxe Markdown descrevendo brevemente o próprio serviço, com informações relevantes para conhecimento, além de ser possível detalhar mais a seu respeito, inserindo badges, para exibir informações relevantes sobre o mesmo, como code coverage nos testes unitários, versão, entre outras.
Um arquivo Dockerfile é o arquivo necessário para a construção da imagem docker do serviço para o seu deploy (ou eventual teste local, se necessário).
Ficando assim com o seguinte layout:
service
\_README.md
\_go.mod
\_go.sum
\_Dockerfile
\_service.toml
\_main.go
IMPORTANTE: É possível criar esta estrutura inicial de um serviço através da ferramenta soma-cli. Consulte-a para mais detalhes.
Layouts opcionais
Configurações
Para o caso de um serviço possuir configurações, ou seja, uma estrutura do tipo Settings declarada num arquivo .proto, ele deve possuir todo o código relacionado ao tratamento desta informação reunido num arquivo específico, de nome settings.go. Desta forma a estrutura básica seria a seguinte:
service
\_README.md
\_go.mod
\_go.sum
\_Dockerfile
\_service.toml
\_main.go
\_settings.go
Lifecycle
Toda inicialização de componentes externos, necessários para o funcionamento do serviço, deve ser realizada utilizando a interface de Lifecycle do Mikros. Isso permite que membros da estrutura principal do serviço sejam inicializados corretamente. Assim como a liberação de algum recurso necessário.
A especificação desta API pode ser consultada no arquivo.
Sendo assim, um serviço que possua esta necessidade deverá ter a seguinte estrutura de arquivos, com o arquivo lifecycle.go sendo utilizado especificamente para inicializações e liberação de recursos do serviço:
service
\_README.md
\_go.mod
\_go.sum
\_Dockerfile
\_service.toml
\_main.go
\_lifecycle.go
Serviços gRPC ou HTTP
Um serviço da categoria gRPC
ou um servidor HTTP
parte da premissa de que um arquivo protobuf também existe para ele, com definições de APIs (RPCs) e entidades. Isto implica que o serviço precisa "implementar" o suporte para esta API definida.
Assim, toda a implementação referente a API gerada pelo protobuf deve ficar reunida num único arquivo fonte, de nome server.go. E a estrutura de um serviço desta categoria ficaria da seguinte maneira:
service
\_README.md
\_go.mod
\_go.sum
\_Dockerfile
\_service.toml
\_main.go
\_server.go
Serviços subscriber ou database-subscriber
Serviços da categoria subscriber
ou database-subscriber
devem possuir um arquivo fonte com o nome subscriber.go onde a declaração de sua struct principal deve ser feita, bem como qualquer código em comum entre os eventos manipulados.
Além disso, o serviço também deve possuir um arquivo fonte específico para cada um dos eventos ouvidos. O nome destes arquivos deve seguir o padrão:
- Ter o mesmo nome do evento (somente o seu sufixo), em caixa baixa e em
snake_case
.
Cada arquivo deve tratar especificamente um evento, com pelo menos uma função que devolva um handler do tipo types/event.EventHandler. Ele também deve conter métodos da struct principal que sejam utilizados somente pelo seu handler.
A criação de um handler deve possuir ao menos as seguintes características:
Uma função específica para "criar" e devolver o handler, para ser chamada na API de inicialização do SDK. O nome desta função deve seguir a regra:
- Iniciar com o prefixo
New
, seguida do nome do evento (somente o seu sufixo), emCamelCase
, com o prefixoHandler
.
- Iniciar com o prefixo
Exemplo para o caso de um evento de nome FILE_CREATED
:
package main
import (
"context"
"github.com/somatech1/mikros/types/event"
)
func NewFileCreatedHandler(service *subscriber) event.EventHandler {
return func(ctx context.Context, e *event.Event) error {
// Trata evento
if err := doSomething(); err != nil {
return event.Skip()
}
return event.Ack()
}
}
A estrutura de código de um repositório para esta categoria de serviço deve conter no mínimo o seguinte (utilizando o evento FILE_CREATED
citado previamente):
service
\_README.md
\_go.mod
\_go.sum
\_Dockerfile
\_service.toml
\_main.go
\_subscriber.go
\_file_created.go
Serviços consumer
Assim como um subscriber, um serviço do tipo consumer também não possui nenhum tipo de especificação formal para sua construção a não ser a necessidade de que o código implemente a interface específica para a sua categoria.
A estrutura de código de um repositório para esta categoria de serviço deve conter no mínimo o seguinte:
service
\_consumer.go
O arquivo consumer.go deve conter a implementação da interfaceConsumptionRegister, bem como os métodos que farão o tratamento dos registros recebidos.