REST (Representational State Transfer) fornece um estilo arquitetural fundamental para a construção de serviços web. No entanto, deixa muitos aspectos da formatação de requisições e respostas indefinidos. Essa ambiguidade pode levar a inconsistências, aumento da sobrecarga de desenvolvimento e uma curva de aprendizado mais íngreme para os consumidores de API. Surge o JSON:API, uma especificação que fornece uma abordagem padronizada e baseada em convenções para a construção de APIs em JSON.
Este guia abrangente oferece um mergulho profundo na especificação JSON:API, explorando seus conceitos centrais, estrutura e recursos poderosos. Dissecaremos seus mecanismos para buscar, criar, atualizar e excluir recursos, gerenciar relacionamentos, lidar com erros e otimizar a transferência de dados, equipando você com o conhecimento para projetar e consumir APIs robustas e eficientes.
Quer uma plataforma integrada e completa para sua Equipe de Desenvolvedores trabalhar em conjunto com produtividade máxima?
Apidog entrega todas as suas demandas e substitui o Postman a um preço muito mais acessível!
Por que JSON:API? Explicado:
Antes de nos aprofundarmos nas complexidades técnicas, é crucial entender os problemas que o JSON:API busca resolver. Sem uma convenção compartilhada, desenvolvedores de API frequentemente gastam um tempo considerável debatendo:
- Estrutura do payload: Como recursos e seus atributos devem ser representados?
- Representação de relacionamentos: Como as conexões entre diferentes recursos devem ser transmitidas?
- Estratégias de busca de dados: Como os clientes podem solicitar campos específicos, incluir recursos relacionados, ordenar, paginar e filtrar dados?
- Relatório de erros: Qual formato as mensagens de erro devem seguir?
O JSON:API aborda essas questões definindo um formato claro e consistente para requisições e respostas. Essa padronização oferece vários benefícios chave:
- Redução de "Bikeshedding": Ao fornecer respostas para questões comuns de design, o JSON:API permite que as equipes se concentrem na lógica de negócio principal de suas aplicações, em vez de debater minúcias de design de API.
- Produtividade Aprimorada: Formatos padronizados significam menos código customizado tanto para produtores quanto para consumidores de API. Bibliotecas de cliente podem ser desenvolvidas para lidar com grande parte do código repetitivo para interagir com qualquer serviço compatível com JSON:API.
- Maior Descobrabilidade e Usabilidade: Estruturas de link consistentes e a clara delimitação de recursos e relacionamentos tornam as APIs mais fáceis de entender e navegar.
- Transferência de Dados Otimizada: Recursos como "sparse fieldsets" (conjuntos esparsos de campos) e "compound documents" (documentos compostos) permitem que os clientes solicitem apenas os dados de que precisam, minimizando os tamanhos dos payloads e reduzindo o número de requisições HTTP.
- Cache Mais Fácil: A especificação promove o uso de mecanismos padrão de cache HTTP.
- Independente de Linguagem: Sendo baseado em JSON, é inerentemente independente de linguagem, facilitando uma ampla adoção em diversas pilhas tecnológicas.
Conceitos Centrais: Os Blocos de Construção de um Documento JSON:API
Em sua essência, o JSON:API gira em torno do conceito de recursos. Um recurso é um registro individual de um tipo particular, como um "artigo", um "usuário" ou um "produto". Cada documento JSON:API, seja uma requisição ou uma resposta, adere a uma estrutura específica.
A Estrutura do Documento: Membros de Nível Superior
Um documento JSON:API é um objeto JSON que deve conter pelo menos um dos seguintes membros de nível superior:
data
: Os "dados primários" do documento. Isso pode ser:- Um único objeto de recurso (por exemplo, ao buscar um artigo específico).
- Um array de objetos de recurso (por exemplo, ao buscar uma coleção de artigos).
- Um único objeto identificador de recurso (para representar um relacionamento um-para-um).
- Um array de objetos identificadores de recurso (para representar um relacionamento um-para-muitos).
null
(por exemplo, quando um relacionamento um-para-um está vazio, ou uma requisição para um único recurso que não existe).- Um array vazio
[]
(por exemplo, quando um relacionamento um-para-muitos está vazio, ou uma requisição para uma coleção não retorna resultados). errors
: Um array de objetos de erro fornecendo detalhes sobre erros de processamento. O membrodata
não deve estar presente seerrors
estiver presente.meta
: Um objeto meta contendo meta-informações não padrão que não se encaixam no restante da especificação.
Além disso, um documento pode conter estes membros de nível superior:
jsonapi
: Um objeto descrevendo a implementação do servidor. Pode incluirversion
(a maior versão JSON:API suportada),ext
(um array de URIs para extensões aplicadas) eprofile
(um array de URIs para perfis aplicados).links
: Um objeto links relacionado aos dados primários. Isso pode incluir links "self", links de recursos relacionados e links de paginação.included
: Um array de objetos de recurso que estão relacionados aos dados primários e/ou entre si. Isso é usado para "documentos compostos" para reduzir o número de requisições HTTP, carregando recursos relacionados lateralmente ("sideloading").
Objetos de Recurso: Representando Seus Dados
Um objeto de recurso é a pedra angular do JSON:API e deve conter:
type
: Uma string que identifica o tipo do recurso (por exemplo,"articles"
,"users"
). Isso ajuda a criar namespaces para recursos e evita colisões de ID entre diferentes tipos.id
: Uma string que identifica unicamente o recurso dentro de seu tipo.
Um objeto de recurso pode também conter:
attributes
: Um objeto attributes contendo dados específicos do recurso. As chaves no objetoattributes
representam as propriedades do recurso (por exemplo,"title"
,"body"
para um artigo). Relacionamentos não devem ser representados no objetoattributes
.relationships
: Um objeto relationships descrevendo as conexões entre o recurso e outros recursos.links
: Um objeto links contendo links relacionados ao recurso, como um linkself
apontando para a URL canônica do recurso.meta
: Um objeto meta contendo meta-informações não padrão sobre o recurso.
Exemplo de um Objeto de Recurso:JSON
{
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON:API Revelado",
"body": "Um mergulho profundo na especificação...",
"created_at": "2025-05-15T10:00:00Z",
"updated_at": "2025-05-16T14:30:00Z"
},
"relationships": {
"author": {
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
},
"data": { "type": "users", "id": "42" }
},
"comments": {
"links": {
"self": "/articles/1/relationships/comments",
"related": "/articles/1/comments"
},
"data": [
{ "type": "comments", "id": "5" },
{ "type": "comments", "id": "12" }
]
}
},
"links": {
"self": "/articles/1"
}
}
Objetos Identificadores de Recurso
Objetos identificadores de recurso são representações mínimas de um recurso, contendo apenas type
e id
. Eles são usados dentro de objetos de relacionamento para vincular a outros recursos sem incorporar o objeto de recurso completo.
Exemplo de um Objeto Identificador de Recurso:JSON
{ "type": "users", "id": "42" }
Objetos Links
Objetos links fornecem URLs para navegar na API. Membros de link comuns incluem:
self
: Um link que representa o próprio recurso ou documento.related
: Um link para um recurso ou coleção relacionada. Frequentemente usado em relacionamentos para buscar os dados relacionados reais.- Links de Paginação:
first
,last
,prev
,next
para navegar em coleções paginadas.
Um link pode ser representado como:
- Uma string simples contendo a URL.
- Um objeto link, que deve conter um
href
(string URL) e pode opcionalmente incluirrel
(tipo de relação),describedby
(link para um documento de descrição),title
,type
(tipo de mídia do alvo),hreflang
e um objetometa
.
Exemplo de um Objeto Links (dentro de um relacionamento):JSON
"links": {
"self": "http://example.com/articles/1/relationships/author",
"related": "http://example.com/articles/1/author"
}
Objetos Meta
Objetos meta permitem a inclusão de meta-informações não padrão. Isso pode ser pares arbitrários de chave-valor. Por exemplo, um objeto meta
poderia incluir informações de direitos autorais ou timestamps relacionados aos dados.
Exemplo de um Objeto Meta:JSON
"meta": {
"copyright": "Copyright 2025 Example Corp.",
"authors": ["John Doe"]
}
Negociação de Conteúdo: Falando a Língua Certa
O JSON:API define seu próprio tipo de mídia: application/vnd.api+json
.
- Header
Accept
: Clientes devem enviar este header com o tipo de mídiaapplication/vnd.api+json
para indicar que esperam uma resposta compatível com JSON:API. Se um servidor não puder satisfazer nenhum dos tipos de mídia no headerAccept
, ele deve responder com um status406 Not Acceptable
. - Header
Content-Type
: Clientes e servidores devem usar este header com o tipo de mídiaapplication/vnd.api+json
para todas as requisições e respostas que contêm um documento JSON:API em seu corpo. Se uma requisição especificar umContent-Type
diferente deapplication/vnd.api+json
(ou outros tipos de mídia registrados que o servidor suporta) e contiver um corpo, o servidor deve responder com um status415 Unsupported Media Type
. Se uma requisição especificarContent-Type: application/vnd.api+json
, mas o corpo não for um documento JSON:API válido, o servidor deve responder com400 Bad Request
.
Os servidores podem suportar outros tipos de mídia juntamente com application/vnd.api+json
através da negociação de conteúdo padrão.
Busca de Dados: Recuperando Recursos e Coleções
O JSON:API fornece mecanismos robustos para que os clientes recuperem dados precisamente conforme necessário.
Buscando Recursos Individuais
Para buscar um único recurso, um cliente envia uma requisição GET
para um endpoint representando esse recurso.
Requisição:
GET /articles/1
Accept: application/vnd.api+json
Resposta Bem-Sucedida (200 OK):JSON
{
"links": {
"self": "/articles/1"
},
"data": {
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON:API é Demais!"
}
// ... outros atributos e relacionamentos
}
}
Se o recurso não existir, o servidor deve retornar um 404 Not Found
. Se um link de recurso relacionado um-para-um for buscado e o relacionamento estiver vazio, os dados primários serão null
.
Buscando Coleções de Recursos
Para buscar uma coleção de recursos, um cliente envia uma requisição GET
para um endpoint representando essa coleção.
Requisição:
GET /articles
Accept: application/vnd.api+json
Resposta Bem-Sucedida (200 OK):JSON
{
"links": {
"self": "/articles",
"next": "/articles?page[offset]=10",
"last": "/articles?page[offset]=50"
},
"data": [
{
"type": "articles",
"id": "1",
"attributes": { "title": "Artigo 1" }
// ...
},
{
"type": "articles",
"id": "2",
"attributes": { "title": "Artigo 2" }
// ...
}
// ... mais artigos
]
}
Se a coleção estiver vazia, o membro data
será um array vazio []
.
Relacionamentos: Conectando Recursos
Relacionamentos são uma parte fundamental da maioria dos modelos de dados. O JSON:API fornece uma maneira clara de defini-los e interagir com eles.
Representando Relacionamentos
Relacionamentos são definidos dentro do objeto relationships
de um recurso. Cada entrada no objeto relationships
representa um relacionamento distinto (por exemplo, "author", "comments").
Um objeto relationship deve conter pelo menos um de:
links
: Contém linksself
erelated
.- O link
self
(URL do relacionamento) permite a manipulação do próprio relacionamento (por exemplo, adicionar/remover itens em um relacionamento um-para-muitos). Quando buscado, retorna objetos identificadores de recurso para os recursos relacionados. - O link
related
(URL do recurso relacionado) permite buscar os objetos de recurso relacionados diretamente. data
: Contém a ligação do recurso (objetos identificadores de recurso).- Para um relacionamento um-para-um: um único objeto identificador de recurso ou
null
. - Para um relacionamento um-para-muitos: um array de objetos identificadores de recurso ou um array vazio
[]
. meta
: Um objeto meta para informações não padrão sobre o relacionamento.
Exemplo de relacionamentos "author" (um-para-um) e "comments" (um-para-muitos):JSON
"relationships": {
"author": {
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
},
"data": { "type": "users", "id": "42" }
},
"comments": {
"links": {
"self": "/articles/1/relationships/comments",
"related": "/articles/1/comments"
},
"data": [
{ "type": "comments", "id": "5" },
{ "type": "comments", "id": "12" }
]
}
}
Buscando Relacionamentos
Os clientes podem buscar informações sobre um relacionamento em si ou sobre os recursos relacionados usando os links fornecidos.
Buscando a Ligação do Relacionamento (link self):
GET /articles/1/relationships/comments
Accept: application/vnd.api+json
Isso retorna uma coleção de objetos identificadores de recurso para os comentários relacionados ao artigo "1".
Buscando Recursos Relacionados (link related):
GET /articles/1/comments
Accept: application/vnd.api+json
Isso retorna uma coleção de objetos de recurso de comentário completos relacionados ao artigo "1".
Otimizando a Recuperação de Dados
O JSON:API oferece vários recursos para otimizar como os dados são recuperados, minimizando a largura de banda e melhorando o desempenho do lado do cliente.
Documentos Compostos: Reduzindo Requisições HTTP com include
Para evitar múltiplas viagens de ida e volta ao servidor para buscar recursos relacionados, o JSON:API permite que os clientes solicitem que recursos relacionados sejam incluídos na resposta primária usando o parâmetro de query include
. O servidor então carregará esses recursos lateralmente ("sideload") no array included
de nível superior.
Requisição para buscar um artigo e incluir seu autor e comentários:
GET /articles/1?include=author,comments
Accept: application/vnd.api+json
Resposta (200 OK):JSON
{
"data": {
"type": "articles",
"id": "1",
"attributes": { "title": "..." },
"relationships": {
"author": {
"data": { "type": "users", "id": "42" }
},
"comments": {
"data": [
{ "type": "comments", "id": "5" },
{ "type": "comments", "id": "12" }
]
}
}
},
"included": [
{
"type": "users",
"id": "42",
"attributes": { "name": "John Doe" }
},
{
"type": "comments",
"id": "5",
"attributes": { "body": "Ótimo artigo!" }
},
{
"type": "comments",
"id": "12",
"attributes": { "body": "Muito informativo." }
}
]
}
- O parâmetro
include
aceita uma lista separada por vírgulas de caminhos de relacionamento. - Relacionamentos aninhados podem ser incluídos usando notação de ponto (por exemplo,
include=comments.author
). - Se um endpoint não suportar
include
, ele deve retornar400 Bad Request
. - O servidor não deve incluir recursos não solicitados na seção
included
.
Sparse Fieldsets (Conjuntos Esparsos de Campos): Buscando Apenas os Campos Necessários
Os clientes podem solicitar que apenas campos específicos (atributos e relacionamentos) sejam retornados para recursos de um determinado tipo usando o parâmetro de query fields[TYPE]
. Isso reduz o tamanho do payload.
Requisição para buscar artigos, mas apenas seus títulos e o relacionamento com o autor:
GET /articles?fields[articles]=title,author
Accept: application/vnd.api+json
Resposta (200 OK):JSON
{
"data": [
{
"type": "articles",
"id": "1",
"attributes": {
"title": "Artigo 1"
},
"relationships": {
"author": {
"data": { "type": "users", "id": "42" }
}
}
}
// ... outros artigos com apenas título e autor
]
}
- O
id
e otype
são sempre incluídos. - Se um cliente solicitar um campo que não existe, o servidor deve ignorá-lo.
- Se um cliente solicitar apenas campos que são relacionamentos, o membro
attributes
pode ser omitido.
Ordenação (Sorting)
Os clientes podem solicitar que os dados primários sejam ordenados usando o parâmetro de query sort
.
Requisição para buscar artigos ordenados por data de criação (descendente) e depois por título (ascendente):
GET /articles?sort=-created_at,title
Accept: application/vnd.api+json
- Um hífen inicial (
-
) indica ordem descendente; caso contrário, é ascendente. - O servidor define quais atributos podem ser usados para ordenação. Requisições para ordenar em atributos não suportados devem resultar em um
400 Bad Request
.
Paginação
O JSON:API suporta várias estratégias de paginação. A especificação define como os links de paginação (first
, prev
, next
, last
) devem aparecer no objeto links
de nível superior. A estratégia de paginação real (por exemplo, baseada em página, baseada em offset, baseada em cursor) é determinada pelo servidor usando parâmetros de query como page[number]
, page[size]
, page[offset]
, page[limit]
ou page[cursor]
.
Exemplo de links de paginação baseada em página:JSON
"links": {
"self": "/articles?page[number]=2&page[size]=10",
"first": "/articles?page[number]=1&page[size]=10",
"prev": "/articles?page[number]=1&page[size]=10",
"next": "/articles?page[number]=3&page[size]=10",
"last": "/articles?page[number]=5&page[size]=10"
}
Os clientes devem usar esses links fornecidos em vez de construir suas próprias URLs de paginação.
Filtragem (Filtering)
A especificação reserva o parâmetro de query filter
para filtrar dados. No entanto, não impõe uma estratégia de filtragem específica. Os servidores podem implementar qualquer estratégia, como filter[attribute]=value
ou filtragem baseada em expressões mais complexas.
Exemplo (recomendado pelo JSON:API, mas não obrigatório):
GET /comments?filter[post]=1 (Obter comentários para o post com ID 1)
GET /comments?filter[post]=1,2&filter[author]=12 (Obter comentários para os posts 1 ou 2, pelo autor 12)
Os clientes devem consultar a documentação da API para entender suas capacidades de filtragem específicas.
Modificando Dados: Criando, Atualizando e Excluindo Recursos
O JSON:API define protocolos claros para operações de manipulação de dados.
Criando Recursos
Para criar um recurso, um cliente envia uma requisição POST
para uma URL representando uma coleção de recursos. O corpo da requisição deve conter um único objeto de recurso com type
e, opcionalmente, attributes
e relationships
. O cliente não deve fornecer um id
para o novo recurso (a menos que IDs gerados pelo cliente sejam suportados e habilitados).
Requisição:
POST /articles
Accept: application/vnd.api+json
Content-Type: application/vnd.api+jsonJSON
{
"data": {
"type": "articles",
"attributes": {
"title": "Título do Novo Artigo",
"body": "Conteúdo do novo artigo."
},
"relationships": {
"author": {
"data": { "type": "users", "id": "42" }
}
}
}
}
Respostas Bem-Sucedidas:
201 Created
: Se o recurso foi criado com sucesso. A resposta deve incluir um headerLocation
identificando a URL do recurso recém-criado. O corpo da resposta deve incluir o recurso recém-criado, incluindo seuid
atribuído pelo servidor.202 Accepted
: Se a requisição de criação foi aceita para processamento, mas o processamento ainda não está completo (por exemplo, para operações assíncronas). A resposta pode incluir um link para monitorar o status.204 No Content
: Se o recurso foi criado com sucesso, mas o servidor opta por não retornar a representação do recurso no corpo da resposta. O headerLocation
ainda é obrigatório.
Se uma tentativa for feita para criar um recurso com um ID gerado pelo cliente que já existe, e o servidor não suportar atualização via POST
, ele deve retornar 409 Conflict
.
Atualizando Recursos
Recursos são atualizados usando o método HTTP PATCH
. A requisição deve incluir o id
do recurso a ser atualizado. O corpo da requisição contém um objeto de recurso com type
, id
e os attributes
e/ou relationships
a serem atualizados.
Requisição para atualizar o título de um artigo e um de seus relacionamentos:
PATCH /articles/1
Accept: application/vnd.api+json
Content-Type: application/vnd.api+jsonJSON
{
"data": {
"type": "articles",
"id": "1",
"attributes": {
"title": "Título do Artigo Atualizado"
},
"relationships": {
"tags": {
"data": [
{ "type": "tags", "id": "3" },
{ "type": "tags", "id": "4" }
]
}
}
}
}
Pontos chave para atualizações:
- Atualizações Parciais: Requisições
PATCH
devem ser parciais. Apenas os campos presentes na requisição devem ser atualizados. Campos não incluídos devem permanecer inalterados. - Atualizando Relacionamentos:
- Um-para-um: Forneça um objeto identificador de recurso ou
null
nosdata
do relacionamento. - Um-para-muitos: Forneça um array de objetos identificadores de recurso. Isso substitui completamente os membros existentes do relacionamento. Para adicionar ou remover membros sem substituir o conjunto inteiro, endpoints de relacionamento dedicados (
/articles/1/relationships/tags
) devem ser usados comPOST
(para adicionar),DELETE
(para remover) ouPATCH
(para substituir todos). - O servidor não deve atualizar atributos ou relacionamentos que não são especificados na requisição.
Respostas Bem-Sucedidas:
200 OK
: Se a atualização foi bem-sucedida e o servidor retorna uma representação do recurso atualizado.202 Accepted
: Se a requisição de atualização foi aceita para processamento, mas ainda não está completa.204 No Content
: Se a atualização foi bem-sucedida, mas o servidor opta por não retornar uma representação.
Se o recurso a ser atualizado não existir, o servidor deve retornar 404 Not Found
.
Atualizando Relacionamentos Diretamente
O JSON:API fornece maneiras específicas de gerenciar relacionamentos sem afetar os atributos do recurso primário.
- Atualizando um Relacionamento Um-para-Um:
PATCH /articles/1/relationships/authorContent-Type: application/vnd.api+json
JSON
{
"data": { "type": "users", "id": "24" } // Atribuir novo autor ou null para limpar
}
- Atualizando um Relacionamento Um-para-Muitos (Substituição Completa):
PATCH /articles/1/relationships/commentsContent-Type: application/vnd.api+json
JSON
{
"data": [
{ "type": "comments", "id": "101" },
{ "type": "comments", "id": "102" }
]
}
- Adicionando a um Relacionamento Um-para-Muitos:
POST /articles/1/relationships/commentsContent-Type: application/vnd.api+json
JSON
{
"data": [
{ "type": "comments", "id": "103" }
]
}
- Removendo de um Relacionamento Um-para-Muitos:
DELETE /articles/1/relationships/commentsContent-Type: application/vnd.api+json
JSON
{
"data": [
{ "type": "comments", "id": "5" }
]
}
Atualizações de relacionamento bem-sucedidas geralmente retornam 200 OK
ou 204 No Content
.
Excluindo Recursos
Para excluir um recurso, um cliente envia uma requisição DELETE
para o endpoint do recurso.
Requisição:
DELETE /articles/1
Accept: application/vnd.api+json
Resposta Bem-Sucedida:
204 No Content
: Se a exclusão foi bem-sucedida e nenhum corpo de resposta é retornado.200 OK
: Se o servidor retorna meta-informações sobre a exclusão.202 Accepted
: Se a requisição de exclusão foi aceita para processamento.
Se o recurso não existir, o servidor deve retornar 404 Not Found
. A especificação não dita como recursos ou relacionamentos relacionados devem ser tratados após a exclusão (por exemplo, exclusões em cascata); isso é um detalhe de implementação.
Tratamento de Erros
Quando um erro ocorre, os servidores devem usar códigos de status HTTP apropriados (4xx para erros do cliente, 5xx para erros do servidor). O corpo da resposta deve conter um documento de erro JSON:API.
Um documento de erro inclui um membro errors
de nível superior, que é um array de objetos de erro. Cada objeto de erro pode conter:
id
: Um identificador único para esta ocorrência particular do problema.links
: Um objeto links contendo:about
: Um link que leva a mais1 detalhes sobre esta ocorrência particular do problema.type
: Um link que identifica o tipo de erro do qual este erro particular é uma instância.status
: O código de status HTTP aplicável a este problema, expresso como uma string.code
: Um código de erro específico da aplicação, expresso como uma2 string.title
: Um resumo curto e legível por humanos do problema.3detail
: Uma explicação legível por humanos específica para esta ocorrência do problema.source
: Um objeto contendo referências à origem do erro no documento de requisição:4pointer
: Um JSON Pointer [RFC6901] para a entidade associada no documento de requisição.parameter
: Uma string indicando qual parâmetro de query URI causou o erro.header
:5 Uma string indicando o nome de um único header de requisição que causou o erro.meta
: Um objeto meta contendo meta-informações não padrão sobre o erro.
Exemplo de Resposta de Erro (422 Unprocessable Entity):JSON
{
"errors": [
{
"status": "422",
"source": { "pointer": "/data/attributes/email" },
"title": "Atributo Inválido",
"detail": "O endereço de e-mail não é válido."
},
{
"status": "422",
"source": { "pointer": "/data/relationships/author" },
"title": "Valor de Relacionamento Inválido",
"detail": "Autor com ID '999' não existe."
}
]
}
Considerações do Lado do Servidor e Melhores Práticas
Embora a especificação central seja abrangente, o JSON:API também fornece recomendações para aspectos como design de URL e nomenclatura de membros.
Design de URL
- Use substantivos plurais para coleções de recursos (por exemplo,
/articles
). - Use
/articles/{id}
para recursos individuais. - Use
/articles/{id}/relationships/{relationshipName}
para links self de relacionamento. - Use
/articles/{id}/{relationshipName}
para links de recursos relacionados.
Nomenclatura de Membros
- Nomes de membros (chaves) devem ser em camel-case (por exemplo,
firstName
) ou usar hifens/underscores como separadores de palavras (por exemplo,first-name
oufirst_name
). A consistência dentro de uma API é fundamental. A própria especificação usa kebab-case para seus parâmetros de query (por exemplo,page[number]
). - Nomes de membros devem conter apenas caracteres alfanuméricos ASCII, hifens e underscores.
Estendendo a Especificação: Extensões e Perfis
O JSON:API é projetado para ser extensível para atender a necessidades em evolução e casos de uso específicos.
Extensões
Extensões podem introduzir novas funcionalidades não cobertas pela especificação base. Um exemplo é a extensão "Atomic Operations", que permite que múltiplas operações (criar, atualizar, excluir) sejam realizadas em uma única requisição atômica. Tanto o cliente quanto o servidor devem entender uma extensão para que ela seja usada. Se um servidor receber uma requisição com uma extensão não suportada, ele deve responder com um erro apropriado.
Perfis
Perfis definem um conjunto de convenções sobre a especificação base para um caso de uso particular (por exemplo, uma maneira específica de lidar com timestamps ou um conjunto comum de atributos meta
). Ao contrário das extensões, os perfis podem ser seguramente ignorados se não forem compreendidos por uma das partes. Eles são destinados a promover a interoperabilidade para padrões comuns sem exigir mudanças na especificação central ou obrigar suporte universal.
Os servidores podem anunciar extensões e perfis suportados no objeto jsonapi
de nível superior. Isso permite que os clientes descubram essas capacidades e adaptem suas requisições de acordo.
O Futuro do JSON:API
O JSON:API continua a evoluir, impulsionado pela contribuição da comunidade e pela necessidade de abordar desafios emergentes de design de API. Seu foco em convenção sobre configuração, eficiência e experiência do desenvolvedor solidificou seu lugar como um padrão líder para a construção de APIs modernas. Ao adotar o JSON:API, as equipes de desenvolvimento podem reduzir significativamente a ambiguidade, aprimorar a interoperabilidade e acelerar o ritmo do desenvolvimento e consumo de API.
Esta exploração detalhada cobre a vasta maioria da especificação JSON:API. Ao entender e implementar esses princípios, os desenvolvedores podem criar APIs que não são apenas funcionais, mas também limpas, consistentes e agradáveis de trabalhar, promovendo, em última análise, um ecossistema de API mais produtivo e colaborativo.