pessoa = {
"nome" : "Cácio Costa",
"empresa": "Alura",
"cargo" : "Instrutor e pagodeiro nas horas vagas"
}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
... Desenvolvimento Web;
... Spring Boot e o ecossistema do Spring (módulos populares);
... SGBDs e Docker.
Aula 1
Estilos de integração
Tecnologias de integração
CORBA, API e suas lições
Desafio
Arquiteturas de integração
Estilos de integração
Considerações
Marcos importantes (1960 - 2024)
RPC
Mensageria
Corba e DCOM
REST
WebServices SOAP
GraphQL, gRPC
e Event-Driven
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
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
A base de uma API
Endpoints/operaçõesO que um cliente é capaz de invocar no sistema remoto
Estruturas de dadosFormato das estruturas trafegadas nas requisições e respostas
ProtocoloO conjunto de regras que rege a comunicação para que os sistemas se entendam.
Elementos fundamentais
DocumentaçãoDetalhamento de como um cliente deve utilizar a API.
"One BUS to rule them all!"
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
Aula 1
11/12 às 11h
→ Introdução às APIs
Aula 2
11/12 às 15h
→ Fundamentos do REST
Aula 2
Fundamentos do REST
Mergulhar fundo no HTTP
Richardson Maturity Model
Desafio
Mão na massa
Origem
Roy Fielding (2000)
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.
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==
Mesmo ingrediente, outro sabor: JSON
URL de um livro da Casa do Código
{
"nome": "Controlando versões com Git e GitHub",
"autores": [
{ "autor": "Alexandre Aquiles" },
{ "autor": "Rodrigo Caneppele" }
],
"paginas": 220,
"ISBN": "978-85-66250-53-4"
}Mesmo ingrediente, outro sabor: XML
Mesma URL de um livro da Casa do Código
<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>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 .xls Excel
O que o servidor fará se você fizer uma requisição
para a URL acima?
GETUsado para obter uma representação de um recurso em uma determinada URL.
POSTCria um novo recurso no servidor, com sua própria URL.
O que deve-se fazer com o recurso
PUTAtualiza ou cria um recurso na URL informada.
DELETEO recurso da URL informada é removido do servidor.
PATCHAtualiza uma representação parcial do recurso da URL informada.
HEADUsado para obter os metadados de um recurso (sem a sua representação).
OPTIONSRetorna os métodos HTTP suportados por uma URL.
TRACERepete o request, para verificar se alguma alteração foi feita por intermediário.
CONNECTRequest vira um túnel TCP/IP para permitir comunicação por um proxy.
Como dizer para o servidor que eu quero
a representação em XML e não em JSON?
AcceptEnumera os formatos aceitos como resposta.
Enviado na resposta para indicar quais origins podem acessar um recurso.
Guiando a conversa entre cliente e servidor
Transporta credenciais de autenticação na requisição.
Indica a representação usada na requisição e na resposta
LocationIndica, na resposta, para indicar redirecionamento ou localização de recurso.
Como o cliente vai saber que foi criada uma nova fatura?
1XX (Informational)A requisição foi recebida e o processamento continua
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.
Comunicação completa
Avaliando o quanto uma API está aderente ao REST
Pântano de POX (Plain Old XML)
Recursos
Métodos HTTP
Controle de Hypermedia (hyperlinks)
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
Aula 3
12/12 às 10h
Design de APIs RESTful
Aula 1
11/12 às 11h
→ Introdução às APIs
Aula 2
11/12 às 15h
→ Fundamentos do REST
Aula 3
HATEOAS
(Hypermedia)
Boas práticas
Documentação e Swagger
Desafio
Mão na massa
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
Links de transição
{
"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
Princípios
"A good API is not just a set of endpoints, but a carefully crafted interface that empowers developers."
Autor desconhecido
Recursos são coisas
| Ruim | Bom |
|---|---|
| /getUsers | /users |
| /article_by_id?id=123 | /articles/{id} |
| /get-pending-orders | /orders?status=pending |
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 |
Prós e contras
Local da versão:
/v1/users/users?version=1application/vnd.company.v1+json
Semântica:
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
Aula
12/12 às 15h
Autenticação e Segurança de APIs REST
Aula 3
12/12 às 10h
Design de APIs RESTful
Aula 2
11/12 às 15h
→ Fundamentos do REST
Aula 4
Segurança em camadas
Zero Trust
Cuidados nas APIs
Desafio
Cuidados no ambiente de execução
Visão geral das integrações
TradicionalMudando a mentalidade
Zero TrustChecklist da aplicação
Integração com OAuth e JWT
Considerações da implementação
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:
Resultado:
Arquivos críticos do sistema podem ser deletados.
ENTRADA: & rm -rf /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:
Resultado:
O script é executado no navegador de outro usuário.
<script>alert('Hacked');</script>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
GET https://server.com?controller=TarefasController&acao=listaTarefasDoUsuario
<?php
$controller = new $_GET['controller'];
$metodo = $_GET['acao']
$controller->$metodo()Path Injection
Descrição:
Ocorre quando um caminho (path) fornecido pelo usuário é concatenado diretamente para manipular arquivos ou URLs.
Impacto:
ENTRADA: /var/data/../../etc/passwdJSON/XML Injection
Descrição:
Ocorre quando entradas maliciosas são usadas para manipular o parser de JSON ou XML da API.
Impacto:
Resultado:
O conteúdo de /etc/passwd é exposto ao atacante.
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<data>&xxe;</data>Diretrizes
Validação e Sanitização de Dados:
Use Bibliotecas Confiáveis:
Limite o Tamanho da Requisição:
Restrinja Diretórios e Caminhos:
Desabilite Recursos Inseguros:
Log e Monitoramento:
Validação de Tipo e Estrutura:
Zero Trust na Infra
Use Imagens de Container Seguras:
Ferramentas:
Docker Security ScanTrivyClair.Zero Trust na Infra
Restringir Privilégios do Container:
root dentro do container.--user para definir um usuário não privilegiado.CAP_SYS_ADMIN.Exemplo:
securityContext:
runAsUser: 1000
runAsGroup: 1000
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
Zero Trust na Infra
Gerencie Segredos com Segurança:
Exemplo:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
data:
username: dXNlcm5hbWU=
password: cGFzc3dvcmQ=Zero Trust na Infra
Isolamento Adequado:
cgroups) para isolar containers no nível do sistema operacional.Ferramentas:
PodSecurityPoliciesValidação de Configurações:
kube-bench ou docker-bench-security.Zero Trust na Infra
Implementar Logs e Monitoramento adequados:
Ferramentas:
FluentdPrometheusGrafana ELK StackZipkinAula
16/12 às 10h
GraphQL
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
Criada internamente no Facebook
Projeto
OpenSource
GraphQL
Foundation
Adoção em massa
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
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
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
Aula
16/12 às 14h
gRPC
Aula
16/12 às 10h
GraphQL
Aula
12/12 às 15h
Autenticação e Segurança de APIs REST
Aula 6
Comparação com HTTP1 - Cenário 1
Serializar um objeto Curso com 5 objetos Pessoa e com um objeto Telefone associados, mostra o tamanho:
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:
Comparação com HTTP1 - Cenário 2 (continuação)
CPU no servidor:
CPU no cliente:
Arquitetura
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.
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;
}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();
}
}
Considerações importantes
Aula
17/12 às 15h
API Gateways e Backend For Frontend (BFF)
Aula
16/12 às 10h
GraphQL
Aula
16/12 às 14h
gRPC
Aula 9
Revisão a jato
Semântica faz toda diferença
Reagindo a acontecimentos importante
Domain Event:
Uma ocorrência significativa em termos de negócio em um determinado Bounded Context.
PedidoRealizado
FaturaPaga
CancelamentoEfetuado
PagamentoRecusado
Natureza da comunicação