A comunicação entre sistemas depende de uma estrutura que permita representar, transmitir e interpretar informações de maneira consistente.
Quando uma aplicação realiza uma requisição para uma API, os dados precisam seguir um formato que possa ser compreendido tanto pelo cliente quanto pelo servidor, independentemente das tecnologias utilizadas em cada lado.
Nesse contexto, formatos como JSON e YAML desempenham um papel importante na serialização e representação de dados. Já o OpenAPI permite descrever formalmente as interfaces de uma API HTTP, documentando seus recursos, parâmetros, operações e respostas.
Embora essas três tecnologias estejam frequentemente presentes no mesmo projeto, elas possuem responsabilidades diferentes.
Compreender suas características e aplicações permite entender melhor como os contratos de comunicação são construídos, documentados e utilizados no desenvolvimento de sistemas.
1. Serialização de dados: por que precisamos de formatos padronizados?
Imagine duas aplicações desenvolvidas em linguagens diferentes: uma utilizando Java e outra Python.
A primeira precisa enviar informações para a segunda. Entretanto, cada linguagem possui suas próprias estruturas internas, tipos de dados e mecanismos de representação.
Como garantir que ambas consigam interpretar as mesmas informações?
Uma alternativa é utilizar um formato independente de linguagem, que permita transformar estruturas de dados em uma representação adequada para armazenamento ou transmissão.
Esse processo está relacionado à serialização.
Serialização é o processo de transformar uma estrutura de dados em uma representação que possa ser armazenada ou transmitida. O processo inverso, que reconstrói a estrutura original a partir dessa representação, é chamado de desserialização.
Por exemplo, considere um objeto que representa um usuário:
public class User {
private Long id;
private String name;
private String email;
}
Essa estrutura pode ser serializada em JSON:
{
"id": 42,
"name": "Vinicius",
"email": "vinicius@example.com"
}
A aplicação que recebe esse conteúdo pode interpretá-lo e reconstruir uma estrutura equivalente utilizando suas próprias ferramentas.
É justamente essa independência que torna formatos como JSON importantes para a integração entre sistemas.
2. JSON (JavaScript Object Notation)
JSON significa JavaScript Object Notation e é um formato textual, leve e independente de linguagem, utilizado para representar e intercambiar dados estruturados.
Apesar de seu nome e de sua origem estarem relacionados ao JavaScript, JSON não é exclusivo dessa linguagem.
Atualmente, é amplamente utilizado em APIs, aplicações web, sistemas distribuídos e mecanismos de armazenamento e configuração.
Uma de suas principais características é a simplicidade de sua estrutura, baseada em pares de chave e valor, arrays e valores primitivos.
2.1. Estrutura e tipos de dados
JSON possui seis tipos fundamentais de valores:
| Tipo | Descrição | Exemplo |
|---|---|---|
| String | Sequência de caracteres | "Vinicius" |
| Number | Número inteiro ou decimal |
42 ou 19.5
|
| Boolean | Valor lógico |
true ou false
|
| Null | Ausência de valor | null |
| Object | Coleção de pares chave-valor | { "id": 42 } |
| Array | Sequência ordenada de valores | [1, 2, 3] |
Um objeto JSON é delimitado por chaves {} e contém propriedades organizadas em pares de chave e valor.
{
"id": 42,
"name": "Vinicius",
"active": true,
"address": {
"city": "Aracaju",
"state": "SE"
},
"skills": [
"Java",
"Spring Boot",
"SQL"
]
}
Observe que objetos podem conter outros objetos e arrays, permitindo representar estruturas hierárquicas.
Essa flexibilidade possibilita representar desde informações simples até estruturas relativamente complexas.
2.2. Características e regras do JSON
Apesar de sua sintaxe simples, JSON possui regras específicas que precisam ser respeitadas.
Algumas delas:
- As chaves dos objetos devem ser strings delimitadas por aspas duplas.
- Strings também devem utilizar aspas duplas.
- Os valores booleanos devem ser escritos em letras minúsculas:
trueefalse. - O valor nulo é representado por
null. - Comentários não fazem parte da sintaxe padrão.
- Os elementos de arrays são separados por vírgulas.
- Pares de chave e valor são separados por dois-pontos.
Por exemplo, a estrutura abaixo é válida:
{
"name": "Maria",
"age": 25,
"active": true
}
Já esta estrutura não é válida:
{
name: 'Maria',
age: 25,
active: True
}
Os problemas estão relacionados à ausência de aspas duplas nas chaves, utilização de aspas simples e escrita incorreta do valor booleano.
2.3. JSON na comunicação HTTP
Uma das aplicações mais comuns do JSON é a representação dos corpos de requisições e respostas HTTP.
Imagine uma aplicação frontend que precisa cadastrar um usuário em uma API.
A requisição poderia ser:
POST /users HTTP/1.1
Host: api.exemplo.com
Content-Type: application/json
{
"name": "Maria",
"email": "maria@example.com"
}
O cabeçalho Content-Type informa o formato do conteúdo enviado.
Nesse caso, application/json indica que o corpo da requisição está representado em JSON.
O servidor recebe os dados, realiza a desserialização, executa as operações necessárias e pode retornar uma representação do recurso criado:
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 43,
"name": "Maria",
"email": "maria@example.com"
}
O JSON permite que diferentes tecnologias compartilhem informações sem depender de uma implementação específica.
É importante destacar que JSON é um formato de representação de dados, não um protocolo de comunicação. Ele pode ser utilizado em diferentes contextos, embora seja especialmente comum em APIs HTTP.
3. YAML (YAML Ain't Markup Language)
YAML é um formato de serialização de dados utilizado principalmente em arquivos de configuração, definição de infraestrutura e descrição de estruturas de dados.
Assim como JSON, é independente de linguagem e permite representar informações estruturadas.
Sua principal característica é a utilização de uma sintaxe baseada em indentação, buscando tornar os documentos mais legíveis para seres humanos.
Observe a representação de um usuário em YAML:
id: 42
name: Vinicius
email: vinicius@example.com
active: true
address:
city: Aracaju
state: SE
skills:
- Java
- Spring Boot
- SQL
A mesma estrutura representada anteriormente em JSON aparece em YAML com menos elementos sintáticos, sem necessidade de chaves, colchetes ou aspas em todos os campos.
Essa característica torna o formato bastante utilizado em arquivos que precisam ser lidos e modificados frequentemente por desenvolvedores.
3.1. Estrutura e características
YAML utiliza principalmente três elementos para organizar suas informações:
Mapeamentos: representam associações entre chaves e valores.
name: Vinicius
age: 18
Sequências: representam listas ordenadas de elementos.
skills:
- Java
- Python
- SQL
Escalares: representam valores individuais, como strings, números, booleanos e valores nulos.
name: Vinicius
age: 18
active: true
Uma característica importante do YAML é a utilização da indentação para estabelecer relações hierárquicas entre os elementos.
Diferentemente do JSON, em que a estrutura é delimitada por caracteres específicos, o YAML utiliza os espaços em branco para determinar os níveis de organização.
Por isso, a consistência da indentação é fundamental.
3.2. YAML e a importância da indentação
Observe o exemplo:
user:
name: Vinicius
address:
city: Aracaju
state: SE
Nesse caso, address pertence a user, enquanto city e state pertencem a address.
Uma alteração inadequada na indentação pode modificar completamente a estrutura do documento ou até provocar erros de interpretação.
Outro detalhe importante é que YAML permite diferentes formas de representação de valores, incluindo strings com aspas, sem aspas e blocos de texto.
Exemplo:
description: API para gerenciamento de usuários
message: "Operação realizada com sucesso"
details: |
Este é um texto que possui
múltiplas linhas.
Essa flexibilidade torna YAML bastante expressivo, mas também exige atenção durante sua utilização.
3.3. Onde YAML é utilizado?
YAML é especialmente comum em ferramentas de infraestrutura, automação e configuração de aplicações.
Alguns exemplos:
Docker Compose
Permite definir serviços, redes e volumes utilizados em uma aplicação.
services:
api:
image: minha-api
ports:
- "8080:8080"
Kubernetes
Utiliza arquivos declarativos para descrever recursos e configurações de infraestrutura.
apiVersion: v1
kind: Pod
metadata:
name: minha-aplicacao
spec:
containers:
- name: api
image: minha-api
GitLab CI/CD
Permite definir pipelines de integração e entrega contínua por meio do arquivo .gitlab-ci.yml.
stages:
- build
- test
build:
stage: build
script:
- echo "Building application"
test:
stage: test
script:
- echo "Running tests"
Esses exemplos demonstram como YAML pode ser utilizado para descrever configurações de maneira declarativa.
Em vez de implementar manualmente cada etapa de uma operação, o desenvolvedor descreve o estado ou comportamento desejado, que será interpretado pela ferramenta responsável.
4. JSON versus YAML: quais são as diferenças?
Embora JSON e YAML permitam representar estruturas semelhantes, existem diferenças importantes entre eles.
| Característica | JSON | YAML |
|---|---|---|
| Sintaxe | Chaves, colchetes e aspas | Indentação e marcadores |
| Comentários | Não possui suporte na sintaxe padrão | Suporta comentários |
| Legibilidade | Estruturado e relativamente compacto | Geralmente mais legível em configurações extensas |
| Tipos de dados | Conjunto limitado e bem definido | Conjunto mais expressivo |
| Uso frequente | Comunicação entre aplicações e APIs | Configurações e infraestrutura |
| Extensões comuns | .json |
.yaml e .yml
|
Nenhum dos formatos é universalmente superior ao outro.
A escolha depende do contexto, das ferramentas envolvidas e das necessidades da aplicação.
JSON é amplamente utilizado na comunicação entre sistemas, especialmente em APIs HTTP.
YAML, por sua vez, é bastante utilizado para descrever configurações e estruturas declarativas.
É importante destacar que YAML possui recursos que vão além do modelo de dados do JSON. Portanto, nem todo documento YAML pode ser convertido diretamente para JSON sem restrições ou perda de informações.
5. OpenAPI: descrevendo contratos de APIs
Até aqui, vimos formatos utilizados para representar dados e estruturas.
Entretanto, existe outra necessidade importante no desenvolvimento de APIs: documentar formalmente como uma aplicação pode ser utilizada.
Imagine uma equipe que desenvolveu uma API com diversos endpoints.
Outros desenvolvedores precisam saber:
- Quais recursos estão disponíveis?
- Quais métodos HTTP podem ser utilizados?
- Quais parâmetros precisam ser enviados?
- Qual é a estrutura do corpo da requisição?
- Quais respostas podem ser retornadas?
- Quais mecanismos de autenticação são necessários?
Uma documentação escrita manualmente pode responder a essas perguntas, mas manter todas essas informações atualizadas conforme a aplicação evolui pode se tornar um desafio.
É nesse contexto que surge o OpenAPI.
O OpenAPI Specification (OAS) é uma especificação independente de linguagem utilizada para descrever interfaces de APIs HTTP de maneira estruturada e padronizada.
Seu objetivo é permitir que pessoas e ferramentas compreendam as capacidades de uma API sem precisar acessar seu código-fonte ou analisar manualmente o tráfego de rede.
Em outras palavras, OpenAPI permite descrever formalmente o contrato de comunicação de uma API.
5.1. O que é um contrato de API?
Um contrato de API define como diferentes aplicações devem interagir.
Ele estabelece informações como:
- Endpoints disponíveis;
- Métodos HTTP suportados;
- Parâmetros obrigatórios e opcionais;
- Estruturas de entrada;
- Estruturas de saída;
- Códigos de status;
- Requisitos de autenticação.
Imagine que uma API disponibilize um endpoint para consultar usuários.
Seu contrato pode estabelecer que:
- O endpoint é
/users/{id}; - O método utilizado é
GET; - O identificador do usuário é obrigatório;
- Uma consulta bem-sucedida retorna
200; - Um usuário inexistente pode resultar em
404; - O corpo da resposta contém os dados do usuário.
Essas informações podem ser descritas em um documento OpenAPI.
Assim, o contrato deixa de depender exclusivamente de explicações textuais e passa a possuir uma representação estruturada que pode ser interpretada por ferramentas.
5.2. Como funciona um documento OpenAPI?
Um documento OpenAPI é uma estrutura que descreve os elementos de uma API.
Ele pode ser escrito em JSON ou YAML.
Na prática, YAML é bastante utilizado por sua legibilidade.
Observe um exemplo simplificado:
openapi: 3.1.0
info:
title: User API
description: API para gerenciamento de usuários
version: 1.0.0
servers:
- url: https://api.exemplo.com
paths:
/users:
get:
summary: Listar usuários
responses:
"200":
description: Lista de usuários retornada com sucesso
post:
summary: Criar usuário
responses:
"201":
description: Usuário criado com sucesso
Vamos compreender os principais elementos.
openapi
Indica a versão da especificação OpenAPI utilizada para descrever o documento.
info
Apresenta informações gerais sobre a API, como nome, descrição e versão.
servers
Define os endereços dos servidores disponibilizados pela API.
paths
Contém os caminhos disponíveis, representando os endpoints da aplicação.
get e post
Representam as operações HTTP disponibilizadas em determinado caminho.
responses
Descreve as possíveis respostas das operações, incluindo códigos de status e suas respectivas informações.
Esse documento já apresenta uma estrutura inicial de descrição, mas ainda pode ser enriquecido com parâmetros, schemas, autenticação, exemplos e outras informações.
5.3. Schemas: descrevendo a estrutura dos dados
Um dos recursos mais importantes do OpenAPI é a possibilidade de descrever formalmente os modelos de dados utilizados pela API.
Isso é feito por meio de schemas.
Imagine uma aplicação que trabalha com usuários. Podemos definir a estrutura esperada de um usuário:
components:
schemas:
User:
type: object
required:
- name
- email
properties:
id:
type: integer
example: 42
name:
type: string
example: Vinicius
email:
type: string
format: email
example: vinicius@example.com
Nesse exemplo, estamos descrevendo um objeto chamado User.
Ele possui três propriedades:
-
id: número inteiro; -
name: texto; -
email: texto com formato de endereço de e-mail.
Além disso, os campos name e email foram definidos como obrigatórios.
Essa descrição permite que ferramentas compreendam a estrutura esperada dos dados e utilizem essas informações para gerar documentação, exemplos e outros recursos.
5.4. Reutilização com $ref
Em APIs maiores, diversos endpoints podem utilizar as mesmas estruturas de dados.
Repetir a definição de um mesmo objeto em diferentes partes do documento pode gerar inconsistências e dificultar sua manutenção.
O OpenAPI permite reutilizar definições por meio da propriedade $ref.
Por exemplo:
paths:
/users:
get:
responses:
"200":
description: Usuários encontrados
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/User"
Nesse caso, a resposta do endpoint utiliza o schema User definido anteriormente.
A referência evita duplicação e facilita a evolução dos contratos.
5.5. Documentação e ferramentas: Swagger e OpenAPI
É comum encontrar os termos Swagger e OpenAPI sendo utilizados como se fossem a mesma coisa.
Entretanto, existe uma distinção importante.
OpenAPI é a especificação que define como uma API HTTP deve ser descrita.
Swagger é o nome de um conjunto de ferramentas relacionadas ao ecossistema OpenAPI.
Entre as ferramentas mais conhecidas estão:
- Swagger UI: apresenta uma documentação interativa da API, permitindo visualizar endpoints, parâmetros e executar requisições.
- Swagger Editor: permite criar e editar documentos OpenAPI.
- Swagger Codegen: permite gerar código cliente, servidor e documentação a partir de especificações.
Essas ferramentas facilitam o trabalho de desenvolvimento e integração, mas não substituem a necessidade de projetar corretamente o contrato da API.
5.6. OpenAPI e geração de código
Uma das vantagens de utilizar uma especificação estruturada é a possibilidade de automatizar tarefas.
A partir de um documento OpenAPI, ferramentas podem gerar:
- Documentação interativa;
- Clientes para diferentes linguagens;
- Interfaces e modelos de dados;
- Estruturas iniciais de servidores;
- Artefatos utilizados em testes e validações.
Por exemplo, uma equipe pode definir o contrato de uma API antes mesmo de implementar seus endpoints.
O frontend e o backend passam a trabalhar a partir da mesma definição, reduzindo ambiguidades sobre os formatos de entrada e saída.
Essa abordagem também é conhecida como API-First Development.
Nela, o contrato da API é projetado e discutido antes da implementação, permitindo alinhar as expectativas entre diferentes equipes e consumidores.
É importante ressaltar que a geração automática não garante, por si só, que a implementação respeite o contrato. Essa conformidade ainda precisa ser verificada.
6. Como JSON, YAML e OpenAPI se relacionam?
Agora que compreendemos cada tecnologia individualmente, podemos observar como elas se complementam.
JSON é um formato utilizado para representar dados estruturados.
YAML também representa dados estruturados, sendo frequentemente utilizado em configurações e documentos declarativos.
OpenAPI, por sua vez, define uma estrutura padronizada para descrever APIs HTTP.
Uma especificação OpenAPI pode ser escrita tanto em JSON quanto em YAML.
Por exemplo, podemos ter um documento OpenAPI escrito em YAML que descreve uma API cujas requisições e respostas utilizam JSON.
Isso demonstra que essas tecnologias não competem entre si. Elas desempenham funções diferentes dentro de uma arquitetura.
Considere o seguinte cenário:
Uma equipe desenvolve uma API REST utilizando Java e Spring Boot.
- O backend recebe requisições HTTP.
- Os dados enviados pelos clientes são representados em JSON.
- A aplicação processa essas informações utilizando suas estruturas internas.
- As respostas são serializadas novamente em JSON.
- Um documento OpenAPI descreve os endpoints, parâmetros, schemas e respostas disponíveis.
- A documentação pode ser apresentada por ferramentas como Swagger UI.
Nesse cenário, cada tecnologia possui uma responsabilidade específica:
| Tecnologia | Responsabilidade |
|---|---|
| JSON | Representar os dados transmitidos. |
| YAML | Representar dados e configurações de maneira estruturada. |
| OpenAPI | Descrever formalmente o contrato da API. |
| Swagger UI | Apresentar a documentação de maneira interativa. |
Essa separação de responsabilidades é importante para compreender como diferentes componentes participam do desenvolvimento e da integração de sistemas.
Conclusão
JSON, YAML e OpenAPI desempenham papéis diferentes, mas complementares na construção de aplicações modernas.
JSON permite representar e transmitir informações de maneira padronizada, sendo amplamente utilizado na comunicação entre sistemas.
YAML oferece uma sintaxe expressiva para representar estruturas de dados e configurações, tornando-se especialmente relevante em ferramentas de infraestrutura e automação.
OpenAPI permite descrever formalmente as interfaces de APIs HTTP, estabelecendo contratos que podem ser compreendidos tanto por desenvolvedores quanto por ferramentas automatizadas.
Compreender essas tecnologias significa entender que a integração entre sistemas não depende apenas da implementação de endpoints. É necessário estabelecer formatos de dados consistentes, documentar as interfaces e garantir que diferentes componentes compartilhem a mesma compreensão sobre o contrato de comunicação.
Uma API bem projetada precisa não apenas funcionar, mas também tornar explícitas as regras que permitem que outros sistemas a compreendam e utilizem corretamente.
Referências
- RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format. Especificação formal do formato JSON.
- RFC 9512 — YAML Media Type. Registro do tipo de mídia YAML e considerações sobre interoperabilidade.
- YAML 1.2 Specification. Especificação da estrutura e sintaxe do YAML.
- OpenAPI Specification (OAS). Especificação para descrição de APIs HTTP.
- Swagger Documentation. Documentação das ferramentas do ecossistema Swagger.
Top comments (0)