Jornada APIs e Integração de Sistemas
pessoa = {
"nome" : "Cácio Costa",
"empresa": "Alura",
"cargo" : "Instrutor e pagodeiro nas horas vagas"
}Jornada
-
Introdução às APIs
-
Fundamentos do REST
-
Design de APIs RESTful
-
Autenticação e Segurança de APIs REST
-
GraphQL
-
gRPC
-
API Gateways e BFF
-
Resiliência em APIs
-
Enterprise Integration Patterns
-
Event-driven Architecture

Seria legal se você soubesse...
-
... Desenvolvimento Web;
-
... Spring Boot e o ecossistema do Spring (módulos populares);
-
... SGBDs e Docker.

Aula 1
Introdução às APIs
1
Estilos de integração
2
Tecnologias de integração
3
CORBA, API e suas lições
5
Desafio
4
Arquiteturas de integração
Integração de sistemas
Estilos de integração






Estilos de integração
Considerações
- Vamos trocar funcionalidades ou apenas dados?
- Quais dados trocaremos?
- Qual protocolo utilizaremos?
- A comunicação será síncrona ou assíncrona?
- Quais ferramentas/frameworks utilizaremos?
- etc.

Evolução das tecnologias
Linha do tempo
Marcos importantes (1960 - 2024)
1960s
RPC
1980s
Mensageria
1990s
Corba e DCOM
2010s
REST
2000s
WebServices SOAP
2020s
GraphQL, gRPC
e Event-Driven
CORBA
A primeira grande tentativa de interoperabilidade universal

-
Desenvolvimento de sistemas distribuídos OO
-
Objetos remotos ou locais
-
-
Estabelecido pela OMG (Object Management Group) em 1991
-
Independência de linguagem
CORBA - Caiu atirando...
Grandes lições
-
A importância de contratos bem definidos entre sistema
-
Os desafios de criar abstrações universais
-
O equilíbrio entre poder e complexidade em APIs
module BankSystem {
interface Account {
void deposit(in float amount);
void withdraw(in float amount);
float balance();
};
};
Exemplo de IDL
Contratos são importantes!
A base de uma API
Endpoints/operações
O que um cliente é capaz de invocar no sistema remoto
Estruturas de dados
Formato das estruturas trafegadas nas requisições e respostas
Protocolo
O conjunto de regras que rege a comunicação para que os sistemas se entendam.
O que é uma API?
Elementos fundamentais
Documentação
Detalhamento de como um cliente deve utilizar a API.
Arquiteturas de integração
ESB centralizado
"One BUS to rule them all!"

Microsserviços
Defina "micro"!

-
Escolha alguns sistemas que se integram dentro da Vivo;
-
Desenhe o fluxo de comunicação entre esses sistemas (ESB, ponto a ponto)
-
Faça uma engenharia reversa e documente parte dessa API
-
Endpoints
-
Operações
-
Estruturas de dados
-
Protocolo
-
Desafio
Nossas aulas
Próxima
Aula 1
11/12 às 11h
→ Introdução às APIs
Atual
Aula 2
11/12 às 15h
→ Fundamentos do REST
Aula 2
Fundamentos do REST
1
Fundamentos do REST
2
Mergulhar fundo no HTTP
3
Richardson Maturity Model
5
Desafio
4
Mão na massa
Fundamentos REST
Origem
"REST provides a set of architectural constraints that, when applied as a whole, emphasizes scalability of component interactions, generality of interfaces, independent deployment of components, and intermediary components."
Roy Fielding (2000)

Fundamentos REST
Restrições e princípios
| Restrição | Descrição |
|---|---|
| Cliente-Servidor | A UI é separada do armazenamento dos dados. |
| Stateless | Sem estado entre requisições. |
| Cache | Rquisições podem ser classificados como cacheáveis. |
| Interface Uniforme | Recursos, métodos, cabeçalhos, etc, padronizados. |
| Sistema em Camadas | Componentes só conhecem a camada imediatamente inferior |
| Código sob Demanda | Cliente pode estender funcionalidades com scripts (opcional) |
Roy chama esse estilo arquitetural da Web de Representational State Transfer, ou simplesmente REST.
Serviços que possuem essa característica de (sufixo ful, em inglês) Web podem ser chamados de RESTful.
Conceitos HTTP
Recurso
Coração do REST
https://cursos.alura.com.br/forum/subcategoria-java/todos/1
amqp://eats:caelum123@rabbitmq:5672
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
Representações
Mesmo ingrediente, outro sabor: JSON
URL de um livro da Casa do Código
- https://www.casadocodigo.com.br/products/livro-git-github
{
"nome": "Controlando versões com Git e GitHub",
"autores": [
{ "autor": "Alexandre Aquiles" },
{ "autor": "Rodrigo Caneppele" }
],
"paginas": 220,
"ISBN": "978-85-66250-53-4"
}Representações
Mesmo ingrediente, outro sabor: XML
Mesma URL de um livro da Casa do Código
- https://www.casadocodigo.com.br/products/livro-git-github
<livro>
<nome>Controlando versões com Git e GitHub</nome>
<autores>
<autor>Alexandre Aquiles</autor>
<autor>Rodrigo Caneppele</autor>
</autores>
<paginas>220</paginas>
<ISBN>978-85-66250-53-4</ISBN>
</livro>Representações
Media Types
Tipos comuns:
text/html-> HTMLtext/plain->texto puroimage/png-> imagens PNGapplication/json-> JSONapplication/xml-> XMLapplication/pdf-> PDFapplication/epub+zip-> ebooks EPUBapplication/vnd.amazon.mobi8-ebook-> ebooks MOBIapplication/vnd.ms-excel-> arquivos.xlsExcel
https://www.vivo.com.br/faturas/2024-12
O que o servidor fará se você fizer uma requisição
para a URL acima?
🤔
GET
Usado para obter uma representação de um recurso em uma determinada URL.
POST
Cria um novo recurso no servidor, com sua própria URL.
Métodos
O que deve-se fazer com o recurso
PUT
Atualiza ou cria um recurso na URL informada.
DELETE
O recurso da URL informada é removido do servidor.
PATCH
Atualiza uma representação parcial do recurso da URL informada.
HEAD
Usado para obter os metadados de um recurso (sem a sua representação).
OPTIONS
Retorna os métodos HTTP suportados por uma URL.
TRACE
Repete o request, para verificar se alguma alteração foi feita por intermediário.
CONNECT
Request vira um túnel TCP/IP para permitir comunicação por um proxy.
GET https://www.vivo.com.br/faturas/2024-12
Como dizer para o servidor que eu quero
a representação em XML e não em JSON?
🤔
Accept
Enumera os formatos aceitos como resposta.
Access-Control-Allow-Origin
Enviado na resposta para indicar quais origins podem acessar um recurso.
Cabeçalhos
Guiando a conversa entre cliente e servidor
Authorization
Transporta credenciais de autenticação na requisição.
Content-type
Indica a representação usada na requisição e na resposta
Location
Indica, na resposta, para indicar redirecionamento ou localização de recurso.
POST https://www.vivo.com.br/faturas
Como o cliente vai saber que foi criada uma nova fatura?
🤔
1XX (Informational)
A requisição foi recebida e o processamento continua
Status code
Feedback para o cliente
2XX (Success)
A requisição foi recebida, entendida e aceita com sucesso
3XX (Redirection)
Mais ações são necessárias para completar a requisição
4XX (Client error)
A requisição é inválida e contém erros causados pelo cliente
5XX (Server error)
O servidor falhou em completar uma requisição válida.
Juntando tudo...
Comunicação completa



Richardson Maturity Model
Avaliando o quanto uma API está aderente ao REST
Nível 0
Pântano de POX (Plain Old XML)

Nível 1
Recursos

Nível 2
Métodos HTTP

Nível 3
Controle de Hypermedia (hyperlinks)
Assunto para a próxima 😎
Mão na massa...
-
Escolha alguns sistemas que se integram dentro da Vivo;
-
Desenhe o fluxo de comunicação entre esses sistemas (ESB, ponto a ponto)
-
Faça uma engenharia reversa e documente parte dessa API
-
Endpoints
-
Operações
-
Estruturas de dados
-
Protocolo
-
Desafio
Nossas aulas
Anterior
Próxima
Aula 3
12/12 às 10h
Design de APIs RESTful
Atual
Aula 1
11/12 às 11h
→ Introdução às APIs
Aula 2
11/12 às 15h
→ Fundamentos do REST
Aula 3
Design de APIs RESTful
1
HATEOAS
(Hypermedia)
2
Boas práticas
3
Documentação e Swagger
5
Desafio
4
Mão na massa
O poder dos links
Navegação
Links para recursos relacionados
{
"id": "12345",
"nome": "João Silva",
"email": "joao.silva@exemplo.com",
"telefone": "+55 11 91234-5678",
"_links": {
"self": {
"href": "https://api.vivo.com.br/clientes/12345"
},
"planos": {
"href": "https://api.vivo.com.br/clientes/12345/planos"
},
"dispositivos": {
"href": "https://api.vivo.com.br/clientes/12345/dispositivos"
},
"faturas": {
"href": "https://api.vivo.com.br/clientes/12345/faturas"
}
}
}
representação HAL+JSON
Máquina de estado
Links de transição

HATEOAS
{
"id":1,
"valor":51.80,
"nome":"ANDERSON DA SILVA",
"numero":"1111 2222 3333 4444",
"expiracao":"2022-07",
"codigo":"123",
"status":"CRIADO",
"formaDePagamentoId":2,
"pedidoId":1,
"_links":{
"self":{
"href":"http://localhost:8081/pagamentos/1"
},
"confirma":{
"href":"http://localhost:8081/pagamentos/1"
},
"recusa":{
"href":"http://localhost:8081/pagamentos/1"
},
"cancela":{
"href":"http://localhost:8081/pagamentos/1"
}
}
}
Transição explícita no próprio recurso
Mão na massa...
Boas práticas
Boas práticas de design
Princípios
- Consistência
- Simplicidade
- Flexibilidade
- Segurança
"A good API is not just a set of endpoints, but a carefully crafted interface that empowers developers."
Autor desconhecido
Nomenclatura de recursos
Recursos são coisas
| Ruim | Bom |
|---|---|
| /getUsers | /users |
| /article_by_id?id=123 | /articles/{id} |
| /get-pending-orders | /orders?status=pending |
- Coleções no plural
- Evita-se verbos na URL
- descreve recurso, não a ação
- Filtros via query string
Métodos e Status
Semântica importa
| Método | Uso típico | Códigos comuns |
|---|---|---|
| GET | Recuperar | 200, 404 |
| POST | Criar | 201, 400 |
| PUT | Atualizar | 200, 204 |
| DELETE | Remover | 200, 204, 404 |
Versionamento
Estratégias e semântica
Prós e contras
Local da versão:
- URI:
/v1/users - Query Param:
/users?version=1 - Header: Accept:
application/vnd.company.v1+json
Semântica:
- 1.0.0 -> 1.0.1 (correção de bug)
- 1.0.0 -> 1.1.0 (nova funcionalidade compatível)
- 1.0.0 -> 2.0.0 (mudanças incompatíveis)
Documentação
OpenApi e Swagger
openapi: 3.0.0
info:
title: Sample API
version: 1.0.0
paths:
/users:
get:
summary: Returns a list of users
responses:
'200':
description: Successful response
Transição explícita no próprio recurso
Exemplo de contrato OpenAPI
- Documentação interativa
- Gerada automaticamente
Mão na massa...
- Crie um serviço simples para gerenciar os planos da Vivo
- Integre o serviço de fatura com o serviço de Plano para pegar detalhes do nome e do valor
Desafio
Nossas aulas
Anterior
Próxima
Aula
12/12 às 15h
Autenticação e Segurança de APIs REST
Aula 3
12/12 às 10h
Design de APIs RESTful
Atual
Aula 2
11/12 às 15h
→ Fundamentos do REST
Aula 4
Autenticação e Segurança de APIs REST
1
Segurança em camadas
2
Zero Trust
3
Cuidados nas APIs
5
Desafio
4
Cuidados no ambiente de execução
Malha de serviços
Visão geral das integrações







Tradicional
- Confia no perímetro
- Verifica uma vez
- IP interno = confiável
- Acesso amplo
Zero Trust Model
Mudando a mentalidade
Zero Trust
- Não confia em nada
- Verifica continuamente
- Localização irrelevante
- Menor privilégio possível
Zero Trust Model
Checklist da aplicação
Integração com OAuth e JWT
- OAuth permite autorização granular
- JWTs com claims específicos para autorização
- Tokens com vida útil curta
Considerações da implementação
- Evitar cookies para autenticação
- Habilitar CORS
- Implementar rigoroso controle de acesso
- Validar dados de entrada
Mão na massa...
Cuidados da aplicação
Exemplos de ataques
Command Injection
Descrição:
Ocorre quando a entrada do usuário é utilizada em comandos de sistema operacional, permitindo que o atacante execute comandos arbitrários.
Impacto:
- Controle completo do servidor.
- Roubo de dados, modificação de arquivos, ou ataques adicionais à infraestrutura.
Resultado:
Arquivos críticos do sistema podem ser deletados.
ENTRADA: & rm -rf /Exemplos de ataques
Cross-Site Scripting (XSS)
Descrição:
Acontece quando entradas maliciosas, como scripts JavaScript, são refletidas na resposta da API ou armazenadas para serem exibidas posteriormente.
Impacto:
- Roubo de sessões e credenciais do usuários
- Execução de scripts maliciosos no navegador do usuário.
- Redirecionamento para sites maliciosos.
Resultado:
O script é executado no navegador de outro usuário.
<script>alert('Hacked');</script>Exemplos de ataques
Remote Code Execution (RCE)
Descrição:
Acontece quando entradas maliciosas, como scripts JavaScript, são refletidas na resposta da API ou armazenadas para serem exibidas posteriormente.
Resultado
- Controle completo do servidor.
- Escalação de privilégios.
- Uso do servidor para atividades maliciosas (ex.: mineração de criptomoedas, envio de spam).
GET https://server.com?controller=TarefasController&acao=listaTarefasDoUsuario
<?php
$controller = new $_GET['controller'];
$metodo = $_GET['acao']
$controller->$metodo()Exemplos de ataques
Path Injection
Descrição:
Ocorre quando um caminho (path) fornecido pelo usuário é concatenado diretamente para manipular arquivos ou URLs.
Impacto:
- Modificação de dados sensíveis.
- Exposição de arquivos internos.
ENTRADA: /var/data/../../etc/passwdExemplos de ataques
JSON/XML Injection
Descrição:
Ocorre quando entradas maliciosas são usadas para manipular o parser de JSON ou XML da API.
Impacto:
- Corrupção ou manipulação de dados.
- Acesso a arquivos locais ou requisições para servidores internos.
Resultado:
O conteúdo de /etc/passwd é exposto ao atacante.
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<data>&xxe;</data>Validações de dados de entrada
Diretrizes
-
Validação e Sanitização de Dados:
- Valide sempre o tipo, formato e tamanho das entradas.
- Remova caracteres especiais ou use codificação segura.
-
Use Bibliotecas Confiáveis:
- Utilize bibliotecas de framework para proteção contra injeções (ex.: Prepared Statements para SQL).
-
Limite o Tamanho da Requisição:
- Configure limites de tamanho para o corpo das requisições.
-
Restrinja Diretórios e Caminhos:
- Nunca concatene diretamente caminhos fornecidos pelo usuário.
-
Desabilite Recursos Inseguros:
- Desabilite suporte a entidades externas em parsers XML.
-
Log e Monitoramento:
- Registre tentativas de entrada maliciosa e monitore padrões incomuns.
-
Validação de Tipo e Estrutura:
- Use schemas para validar JSON/XML, como JSON Schema ou ferramentas de validação de contratos.
Cuidados com o ambiente de execução
Práticas de segurança
Zero Trust na Infra
Use Imagens de Container Seguras:
- Sempre use imagens oficiais ou de fontes confiáveis.
- Digitalize imagens antes de usá-las para verificar vulnerabilidades.
- Mantenha as imagens atualizadas regularmente.
Ferramentas:
Docker Security ScanTrivyClair.
Práticas de segurança
Zero Trust na Infra
Restringir Privilégios do Container:
-
Execute containers com o menor privilégio possível (non-root container):
- Não use o usuário
rootdentro do container. - Use a flag
--userpara definir um usuário não privilegiado.
- Não use o usuário
- Desative capacidades perigosas do Linux, como
CAP_SYS_ADMIN.
Exemplo:
securityContext:
runAsUser: 1000
runAsGroup: 1000
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
Práticas de segurança
Zero Trust na Infra
Gerencie Segredos com Segurança:
- Não armazene segredos diretamente dentro do container.
- Use gerenciadores de segredos, como AWS Secrets Manager, HashiCorp Vault, ou Kubernetes Secrets.
- Sempre criptografe segredos em trânsito e em repouso.
Exemplo:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
data:
username: dXNlcm5hbWU=
password: cGFzc3dvcmQ=Práticas de segurança
Zero Trust na Infra
Isolamento Adequado:
- Use namespaces e control groups (
cgroups) para isolar containers no nível do sistema operacional.
Ferramentas:
PodSecurityPolicies
Validação de Configurações:
- Verifique configurações do Docker e Kubernetes com ferramentas como
kube-benchoudocker-bench-security.
Práticas de segurança
Zero Trust na Infra
Implementar Logs e Monitoramento adequados:
- Configure o logging adequado para monitorar atividades anômalas.
- Monitore integração de serviços com OpenTracing
Ferramentas:
FluentdPrometheusGrafanaELK StackZipkin
E não para por aqui...
- Execute o keycloak e import o realm do arquivo "realm-desenvolvimento.json"
- Configure os serviços para validarem tokens
Desafio
Nossas aulas
Anterior
Próxima
Aula
16/12 às 10h
GraphQL
Atual
Aula 3
12/12 às 10h
Design de APIs RESTful
Aula
12/12 às 15h
Autenticação e Segurança de APIs REST
Aula 5
GraphQL

Linha do tempo
2012
Criada internamente no Facebook
2015
Projeto
OpenSource
2018
GraphQL
Foundation
2024
Adoção em massa

Todo poder emana do cliente!

GraphQL vs REST


Demo rápida

Schema, tipos e operações

Coração do GraphQL
type Cliente {
id: ID!
nome: String!
email: String!
faturas: [Fatura!]!
}
type Fatura {
id: ID!
valor: Float!
vencimento: String!
clienteId: ID!
status: StatusFatura!
}
enum StatusFatura {
ABERTA
ATRASADA
PAGA
}Tipos complexos
type Query {
consultaCliente(id: ID!): Cliente
pesquisaFaturasDoCliente(clienteId: ID!): [Fatura!]!
pesquisaFaturasPorStatus(
clienteId: ID!,
StatusFatura: status!
): [Fatura!]!
}
type Mutation {
cadastraCliente(
cliente: NovoClienteInput!
): Cliente
registraPagamento(faturaId: ID!): Boolean!
}
input NovoClienteInput {
nome: String!
email: String!
}Definição de operações
Anatomia de um comando

Payload e retorno
type Query {
consultaCliente(id: ID!): Cliente
}Definição da Query
query {
consultaCliente(id: "1") {
# Campos que deseja receber (não listou email)
id
nome
faturas {
valor
status
}
}
}Payload enviado
Resolvers e Netflix DGS

Implementando a busca
query {
consultaCliente(id: "1") {
id
nome
faturas {
valor
status
}
}
}Payload enviado
Payload enviado
@DgsComponent
public class ClientePorId {
private ClienteRepository clienteRepo;
private FaturaRespository faturaRepo;
@DgsQuery
public Cliente consultaCliente(@InputArgument Long id) {
return clienteRepo.getReferenceById(id);
}
@DgsData(parentType = "Cliente", field = "faturas")
public List<Fatura> buscaFaturasDoCliente(DgsDataFetchingEnvironment env) {
Cliente cliente = env.getSource();
return faturaRepo.findByClienteId(cliente.getId());
}
}Implementação no Spring Boot
Mão na massa...


- No serviço de pagamento:
- Criar enum para status do Pagamento
- Queries:
- listar todos os pagamentos
- pesquisar pagamentos por status
- Mutations:
- cancelar pagamento
Desafio
Nossas aulas
Anterior
Próxima
Aula
16/12 às 14h
gRPC
Aula
16/12 às 10h
GraphQL
Atual
Aula
12/12 às 15h
Autenticação e Segurança de APIs REST
Aula 6
gRPC e Protocolos Binários

Protocolos binários
Comparação com HTTP1 - Cenário 1
Serializar um objeto Curso com 5 objetos Pessoa e com um objeto Telefone associados, mostra o tamanho:
- Protocol Buffers: 250
- Thrift TCompactProcotol: 278
- Thrift TBinaryProtocol: 460
- HTTP/JSON: 559
- HTTP/XML: 836
- RMI: 905


Protocolos binários
Comparação com HTTP1 - Cenário 2
Executar 10.000 chamadas por uma listagem de códigos de Curso e, em seguida, os dados do Curso associado a esse código.
Avalia: tempo de resposta e uso de CPU no servidor e no cliente.
Tempo de resposta:
- Thrift TCompactProcotol: 01 min 05 s
- Thrift TBinaryProtocol: 01 min 13 s
- Protocol Buffers: 01 min 19 s
- RMI: 02 min 14 s
- HTTP/JSON: 04 min 44 s
- HTTP/XML: 05 min 27 s

Protocolos binários
Comparação com HTTP1 - Cenário 2 (continuação)
CPU no servidor:
- Thrift TBinaryProtocol: 33 %
- Thrift TCompactProcotol: 30 %
- Protocol Buffers: 30 %
- HTTP/JSON: 20 %
- RMI: 16 %
- HTTP/XML: 12 %
CPU no cliente:
- Thrift TCompactProcotol: 22.5 %
- Thrift TBinaryProtocol: 21 %
- Protocol Buffers: 37.75 %
- RMI: 46.5 %
- HTTP/JSON: 75 %
- HTTP/XML: 80.75 %

gRPC
Arquitetura






Tipos de canais
Todo o poder o HTTP2
Unary (request/response)
O cliente envia um request para o servidor e espera um response
Server Streaming
O cliente envia uma requisição e o servidor responde com um fluxo de dados.
Client Streaming.
O cliente envia um fluxo de dados e o servidor responde com uma única resposta.
Bidirectional Streaming
Tanto o cliente e o servidor trabalham com fluxos de dados.

Protocol Buffer
Descrevendo a comunicação

syntax = "proto3";
package plano.service; // não deve ser nome invertido
option java_package = "br.com.alura.fatura.plano"; // pacote na convenção Java
service Plano {
rpc ListaPlanos (ListaPlanosRequest) returns (RegistraPagamentoResponse) {}
rpc PlanoPorId (IntValue) returns (Plano) {}
}
message ListaPlanosRequest {
string tipo = 1;
}
message ListaPlanosResponse {
repeated Plano planos = 1;
}
message Plano {
int64 id = 1;
string nome = 2;
string tipo = 3;
}
message IntValue {
int64 value = 1;
}Implementando o serviço
Descrevendo a comunicação

@GrpcService
public class PlanoService extends PlanoServiceGrpc.PlanoServiceImplBase {
@Autowired
private PlanoRepository planoRepository;
@Override
public void listaPlnos(ListaPlanosRequest request,
StreamObserver<ListaPlanosResponse> responseObserver) {
ListaPlanosResponse response = ListaPlanosResponse.newBuilder();
planoRepository.findAll()
.map(plano -> {
return Plano.newBuilder() // mensagem gerada
.setId(plano.getId())
.setNome(plano.getNome())
.setTipo("Mensal")
.build();
})
.forEach(response::add);
responseObserver.onNext(response.build());
responseObserver.onCompleted();
}
}
Boas práticas
Considerações importantes
-
Versionamento de serviços
- Compartilhamento dos arquivos .proto
- Tratamento de erros
- Deadlines e timeouts
- Monitoramento e tracing

"Mão na massa..."
😅

Nossas aulas
Anterior
Próxima
Aula
17/12 às 15h
API Gateways e Backend For Frontend (BFF)
Aula
16/12 às 10h
GraphQL
Aula
16/12 às 14h
gRPC
Atual
Aula 9
Event-driven Architecture
É "só" mensageria com outra mentalidade
Revisão a jato
Tipos de mensagem
Semântica faz toda diferença

Domain events
Reagindo a acontecimentos importante
Domain Event:
Uma ocorrência significativa em termos de negócio em um determinado Bounded Context.
PedidoRealizado
FaturaPaga
CancelamentoEfetuado
PagamentoRecusado
Event-driven Architecture
Conceitos-chave
Natureza da comunicação

Jornada APIs e Integração de Sistemas
By cacio-costa
Jornada APIs e Integração de Sistemas
- 25