swift-microservices/swift-microservices-architect

Arquiteta backends Swift como microsserviços gRPC atrás de um gateway Hummingbird, com um pacote Swift por serviço, um Core de casos de uso com typed throws, um target adaptador por tecnologia (Postgres com segurança em nível de linha, gRPC, Temporal, Valkey) e uma raiz de composição executável. Utilize ao planejar um backend Swift ou dividi-lo em serviços, desenhar limites de módulos ou escrever Package.swift, adicionar um serviço, endpoint, caso de uso, repositório, migração, tabela multi-tenant ou workflow Temporal durável, configurar injeção de dependências, desligamento gracioso, autenticação mTLS ou JWT, nomear tipos e targets de servidor, configurar CI/CD de um pacote no GitHub Actions, ou revisar a arquitetura ou estilo de código de um servidor Swift, mesmo quando o usuário não nomeia a arquitetura.

O que é swift-microservices-architect?

Este skill define uma arquitetura completa para construir backends Swift como microsserviços gRPC por trás de um gateway Hummingbird. Ele organiza o código em pacotes Swift separados por serviço, com um pacote Core compartilhado contendo casos de uso com `typed throws`, e targets adaptadores para tecnologias específicas (Postgres com segurança em nível de linha, gRPC, Temporal, Valkey). A raiz de composição de cada serviço (um executável) é responsável por ler a configuração, construir clients e iniciar o `ServiceGroup`. As regras são rígidas: o Core nunca importa drivers ou transportes, adaptadores nunca importam uns aos outros, e tipos de contrato gerados não vazam dos targets de gRPC. O skill inclui checklists detalhados para planejar um backend, adicionar um serviço, operação, processo durável (workflow Temporal), configurar CI/CD e revisar um backend existente. Ele exige Swift 6 com configurações específicas (`ExistentialAny`, `MemberImportVisibility`, etc.) e impõe um estilo de código que prioriza clareza, tratamento de erros por camadas e uso restrito de concorrência não verificada.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/swift-microservices/swift-microservices-architect-skill/tree/HEAD/skills/swift-microservices-architect

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Arquiteto de Microsserviços Swift

Em um backend construído de outra forma, mantenha sua estrutura e convenções a menos que o usuário peça para alterá-las, e adote a forma deste skill apenas para o que o backend não possui.

X representa um serviço no nome de um target (LoansCore) e para o que um tipo é nomeado (BorrowBookUseCase, LoanService); <Org> e <org> para a organização. Os exemplos são Bookshelf, uma pequena biblioteca de empréstimos:

PacoteContém
bookshelf-identityContas, senhas, sessões; emite todo token de acesso; códigos de redefinição no Valkey; membros para outros serviços, internamente
bookshelf-catalogLivros: qualquer um lê, administradores editam; Loans consulta livros internamente
bookshelf-loansEmpréstimos de um membro, uma tabela tenant; um workflow marca um empréstimo como atrasado e envia um aviso
bookshelf-gatewayA API HTTP pública, encaminhando para os contratos gRPC dos serviços
bookshelf-coreBookshelfAuthentication, BookshelfPersistence, BookshelfTransport, BookshelfTesting
bookshelf-protosIdentityProtos, CatalogProtos, LoansProtos

A forma

Clientes ── HTTPS ──► borda (TLS termina) ── HTTP ──► Gateway (Hummingbird, OpenAPI)
Gateway ── gRPC, mTLS, o JWT do chamador ──► XService de cada serviço
Serviço, worker ── gRPC, mTLS ──► XInternalService de outro serviço
Serviço, worker ── mTLS ──► Temporal          Serviço ──► seu próprio banco de dados Postgres, Valkey

Todo serviço e o gateway dependem de <org>-core, <org>-protos e das bibliotecas swift-microservices (stack).

Pacote de um serviço

<org>-x
├── XCore         modelos de domínio, erros, protocolos de repositório e comandos, portas, casos de uso
├── XPostgres     um escopo por função de banco de dados, repositórios, statements, migrações
├── XGRPC         XService e XInternalService, conversões Protobuf, clients gRPC para as portas do Core
├── XTemporal     workflows, contêineres de atividades, o client Temporal para a porta de workflow do Core
├── XValkey       repositórios para valores de curta duração
├── X<Provider>   uma API de terceiros por trás de uma porta do Core (LoansResend)
└── X             executável: comandos, padrões de configuração, migrações, raízes de composição

Um serviço tem apenas os targets que precisa, e cada um importa apenas o que sua linha lista. Regras rígidas:

  • XCore não importa driver, transporte, contrato, mecanismo de workflow, módulo de configuração ou ciclo de vida (o que Core pode linkar).
  • Targets adaptadores nunca importam uns aos outros; o executável entrega um para o outro através dos protocolos do Core.
  • Tipos de contrato gerados nunca saem de XGRPC, do target HTTP do gateway e de executáveis.
  • Apenas um executável lê configuração, constrói clients e executa o ServiceGroup.
  • Nenhum serviço lê o banco de dados de outro; dados cruzam serviços apenas através de contratos.

Quem é dono do quê

PreocupaçãoDono
Regras de negócio, decisões de autorização, o que um erro significaO caso de uso, no XCore; adaptadores apenas convertem e delegam
O que um serviço sabe sobre os dados de outroUm modelo no Ports/ do seu XCore, ao lado da porta que o retorna
Protobuf ↔ domínio, HTTP ↔ protobufConversões Protobuf/ do XGRPC; Schemas/ do gateway
Mensagens entre processos; a API pública<org>-protos; openapi.yaml do gateway
Quem é o chamadorO gateway verifica e encaminha o token; cada serviço o verifica novamente
Quais processos podem chamar um RPC internomTLS no listener: todo processo que a autoridade do ambiente assina
Isolamento de tenantSegurança em nível de linha; <Org>Persistence vincula o chamador a cada transação, e os casos de uso de cada audiência executam como sua função de banco de dados
Trabalho durável, atrasado ou multi-serviçoUm workflow Temporal no XTemporal
O que todo serviço precisa de forma idêntica<org>-core: identidade, vinculação de tenant, leitores de transporte

Estilo de código

O código lê como o requisito que implementa, com o código de exemplo da WWDC da Apple como referência (style). Casos de uso e adaptadores mapeiam erros desta forma:

do {
    ...  // o trabalho, na ordem que o requisito declara
} catch let error as BorrowBookUseCaseError {
    throw error
} catch CatalogClientError.unavailable {
    logger.warning("Falha no empréstimo: catálogo indisponível")
    throw .catalogUnavailable
} catch {
    logger.error("Falha no empréstimo: erro desconhecido", metadata: ["error": "\(String(reflecting: error))"])
    throw .unknown
}
  • Um do contém o trabalho até seu return, e cada catch termina seu próprio caminho: nada é declarado antes do do para um catch preencher.
  • Construa, então chame: um valor que uma chamada recebe é um let nomeado, nunca uma conversão, try ou await nos argumentos (construa, então chame).
  • Sem métodos auxiliares em casos de uso, workflows ou atividades, e sem manipulação de Result, flags de direção, try?, do aninhado em um catch, ou force unwraps.
  • Modo Swift 6 com ExistentialAny, MemberImportVisibility, InternalImportsByDefault e NonisolatedNonsendingByDefault (configurações Swift); acesso package entre targets de um serviço.
  • Tudo que cruza uma fronteira é Sendable; sem Task {} ou Task.detached, e concorrência não verificada apenas onde concorrência permite.

Pegadinhas

  • Um componente deixado de fora do ServiceGroup nunca executa: um GRPCClient ou PostgresClient não executado nunca conecta, então suas chamadas esperam até o deadline.
  • Um processo conectado como proprietário do banco de dados ignora a segurança em nível de linha, então todo processo conecta como suas funções e apenas serve --migrate-database como proprietário.
  • Temporal verifica Codable apenas em tempo de execução: toda carga útil de workflow e atividade, e cada tipo que ela contém, é Codable, Sendable (workflows).
  • O código do workflow é reproduzido: Date.now, UUID(), aleatoriedade, Task.sleep ou qualquer I/O em um workflow quebra a determinismo.
  • Um import Foundation simples ou com escopo no código próprio vincula Foundation completo no Linux; use o import condicional FoundationEssentials.

Checklists

Copie a checklist da tarefa na resposta e marque os itens conforme forem concluídos; cada arquivo .md nomeado está em references/.

Planejar um backend

- [ ] As capacidades e os dados que cada uma possui; um serviço por capacidade (system.md#splitting-a-system-into-services)
- [ ] Nomear cada serviço; verificar seus nomes de target contra cada módulo no grafo
- [ ] Por serviço: RPCs XService por audiência, RPCs XInternalService e chamadores sem ciclo de chamada, tabelas (tenant ou não), workflows, estado de curta duração
- [ ] Por serviço: seus targets, comandos e funções de banco de dados
- [ ] Produtos de <org>-core, contratos de <org>-protos, rotas do gateway por camada
- [ ] Ordem de construção: <org>-core e <org>-protos, o emissor de token, cada serviço antes de seus chamadores, o gateway
- [ ] Escrever o plano a partir de system.md#the-plan; verificar contra as regras rígidas antes de qualquer código

Adicionar um serviço

- [ ] <org>-protos: XProtos com XService, e XInternalService se processos chamarem
- [ ] Pacote <org>-x a partir de packages.md#packageswift-template, com apenas os targets que o plano nomeia
- [ ] XCore: modelos, erros, repositórios, portas, um caso de uso por RPC (use-cases.md)
- [ ] XPostgres: funções, tabelas, segurança em nível de linha, statements, um escopo por função (persistence.md)
- [ ] XGRPC: serviços proto sobre os casos de uso, conversões, clients para portas (grpc.md)
- [ ] XTemporal, XValkey, X<Provider> conforme o plano precisar
- [ ] X: comandos, padrões InMemoryProvider, Migrações, Serve e Run com um worker (composition.md)
- [ ] Gateway: rotas para os RPCs públicos (gateway.md)
- [ ] Um target de teste por módulo, sobre mocks (testing.md)
- [ ] Seus workflows CI, Containerfile e Dependabot como um serviço (delivery.md)
- [ ] swift build e swift test; corrigir e repetir até ambos passarem sem avisos

Adicionar uma operação

- [ ] Contrato: o RPC sob sua audiência em XService, ou em XInternalService
- [ ] XCore: os cinco arquivos do caso de uso; seu escopo lista apenas o que toca (use-cases.md)
- [ ] XPostgres: os escopos das funções sob as quais pode executar adotam seu protocolo de escopo
- [ ] XGRPC: o handler e a conversão da entrada, cada caso de erro mapeado
- [ ] Executável: o caso de uso no banco de dados de sua função, passado ao serviço
- [ ] Gateway: a rota em sua camada, se pública
- [ ] Testes: os resultados do caso de uso e os status do handler, sobre mocks
- [ ] swift build e swift test; corrigir e repetir até ambos passarem sem avisos

Adicionar um processo durável

- [ ] XCore: a porta XWorkflowClient; os casos de uso que suas atividades executam, adotados pelo escopo do worker
- [ ] XTemporal: o workflow, suas atividades, TemporalXWorkflowClient, ActivityOptions nomeadas (workflows.md)
- [ ] O caso de uso que o inicia, após sua transação ser confirmada, por um id determinístico
- [ ] Executável: o client Temporal no Serve; o grupo de workers e sua raiz Run
- [ ] Testes: o workflow no servidor de salto de tempo, suas atividades sobre mocks
- [ ] swift build e swift test; corrigir e repetir até ambos passarem sem avisos

Configurar CI/CD

- [ ] O tipo do pacote: biblioteca pública, biblioteca de sistema ou serviço (delivery.md#package-kinds)
- [ ] Seus workflows CI, chamando swift-microservices/ci no commit de um release; dependabot.yml; .license_header_template e .licenseignore; os segredos
- [ ] Uma biblioteca: os labels semver e .github/release.yml; um serviço: seu Containerfile
- [ ] swift build e swift test com as flags do CI; corrigir e repetir até ambos passarem

Revisar um backend

- [ ] Executar as verificações de fronteira (packages.md#checking-the-boundaries)
- [ ] Cada caso de uso: seus cinco arquivos, typed throws, um catch por caso, sem helpers, a função de banco de dados correta
- [ ] Cada adaptador apenas converte e delega; todo caso de erro é mapeado
- [ ] Cada raiz: configuração lida apenas lá, todo componente no ServiceGroup em ordem de dependência
- [ ] Configurações Swift, imports FoundationEssentials, acesso package, nomenclatura (conventions.md)
- [ ] Achados classificados como bloqueantes (isolamento de tenant, autorização, credenciais, construção), principais (as formas), menores (nomenclatura, layout, logging), cada um citando um arquivo e linha ou um grep vazio, com a regra e a correção; então as decisões do usuário. Alterar código apenas quando solicitado
- [ ] swift build e swift test; relatar cada resultado, ou por que não pôde executar

Referências

Leia a referência para a parte em questão:

ReferênciaAbrange
system.mdDivisão em serviços, contratos, como serviços se comunicam, pacotes compartilhados, o plano
packages.mdTargets e seus imports, Package.swift, configurações Swift, traits e Foundation, layouts, verificações de fronteira
stack.mdAs bibliotecas, qual target linka cada, linkagem de Foundation, escolha de versões
use-cases.mdModelos, erros, repositórios, portas, os cinco arquivos de um caso de uso e corpo, transações, autorização
persistence.mdEscopos por função de banco de dados, segurança em nível de linha, statements, migrações, Valkey
grpc.mdContratos, serviços proto, handlers, conversões, paginação, códigos de status, clients, transportes
gateway.mdTipos OpenAPI, contextos de requisição e camadas, controllers, webhooks, erros, clients upstream
workflows.mdIniciar workflows, payloads, determinismo, atividades e opções, versões, o worker
composition.mdComandos, raízes de composição, configuração, logging, o ServiceGroup
security.mdO modelo de confiança, mTLS, tokens de usuário, camadas de autorização, segredos, webhooks
style.mdComo o código se lê: erros, concorrência, imports, Foundation, tipos, formatação
testing.mdTargets de teste, o que cada um prova, mocks
delivery.mdWorkflows CI por tipo de pacote, releases, implantação, Containerfile, Dependabot
conventions.mdNomear pacote, target, tipo, arquivo, chave ou pasta

Skills relacionados

Para o código dentro das formas, carregue estes quando instalados; onde este skill declara uma forma, siga-a:

  • Atores, grupos de tarefas, cancelamento, diagnósticos Sendable, migração Swift 6: swift-concurrency
  • Rótulos de argumento, nomes de método, comentários de documentação: swift-api-design-guidelines
  • Testes de casos de uso, handlers e workflows: swift-testing-expert

Habilidades Relacionadas