You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Olá. Acabei de conhecer o projeto e vi que já houve uma discussão sobre versionamento #12 que levou ao PR #25. Apesar de não existir uma forma correta de se fazer versionamento[1], gostaria de propor um modelo diferente que acho que seria mais vantajoso para esse projeto.
Contexto
Levando em conta que esse projeto criará uma API pública que potencialmente será utilizada por diversos clientes, acredito que é de extrema importância manter o processo de desenvolvimento o mais eficiente possível. Em minha experiência, resource versioning ou global uri versioning adicionam algumas complexidades no desenvolvimento da API que acabam desacelerando a sua evolução:
Manutenção: breaking changes normalmente levam a criação de outro endpoint, o que leva a manutenção de duas ou mais implementações distintas (no caso de múltiplas versões) além do planejamento paralelo para descontinuar cada versão. Imaginem como será para resolver bugs que afetam múltiplas versões por exemplo.
Obriga atualização nos clientes: Esse modelo de versionamento normalmente adiciona mais trabalho para os clientes se manterem atualizados.
Pessoalmente eu também acho que URI versioning tira um pouco o charme de uma REST(ful) API já que não considero a versão um recurso ou sub-recurso. Lembrando que o pilar de uma REST API são os recursos e as operações que posso fazer nos mesmos.
Proposta
Manter a URI consistente (sem versão) e utilizar content negotiation (utilizando Accepts e Content-Type headers) para negociar qual conteúdo o cliente precisa. Em outras palavras, negociar a versão. Na prática a API evoluiria mantendo compatibilidade com as versões anteriores e os endpoints seriam os mesmos. Essa abordagem é utilizada no ambiente empresarial[2 e 3].
Mas enfim, como seria isso na prática?
Antes:
GET /api/v1/cep/[cep]
Depois:
# O serviço é uma API (e nada mais). Não vejo necessidade de adicionar /api na URI, mas não tenho nada contra
/cep/:id
Guidelines
Considerando o Pull Request #101 e Issue #14 , teríamos os seguintes guidelines:
OpenAPI permite adicionar a versão em #/info/version (recomendo não usar as regras 9 e 10). Exemplo:
openapi: 3.0.1
info:
title: CEP API
description: API for <...>
version: 1.3.7
<...>
Apesar de não ter um impacto direto no funcionamento da API, esses metadados dão visibilidade e informações sobre a API para os clientes.
Usar media type versioning
Versionamento baseado em negociação de conteúdo reduz o acoplamento e facilita a evolução da API. A versão (ou conteúdo) são negociados usando o cabeçalho Content-Type e Accept do protocolo HTTP. Por exemplo: application/brasil.cep+json;version=2. Para manter compatibilidade, cada breaking change (major release) cria um novo tipo (media type). Assim, os recursos (URI) e a semântica das operações são mantidas enquanto o versionamento é limitado ao tipo de conteúdo.
Teríamos as seguintes regras:
Usar media types personalizados para versões diferentes. No jargão de semantic release seria criar um novo media type quando tivermos um major release. Enquanto não tivermos nenhuma mudança de versão é melhor se manter utilizando o padrão: application/json
Incluir versões no cabeçalho do request e response para dar visibilidade
Incluir Content-Type no cabeçalho Vary para permitir cache de versões diferentes em qualquer proxy que esteja no caminho:
custom-media-type é o recurso. Exemplo: brasil.cep
version é a versão. Exemplo: 2
Exemplo
Suponha que o cliente queira apenas a nova versão:
Accept: application/brasil.ce+json;version=2
Um servidor deve responder, assim como um cliente enviando uma requisição com conteúdo (POST por exemplo), usando o cabeçalho Content-Type do protocolo HTTP para declarar explicitamente qual versão do conteúdo esta sendo enviada:
Definir regras/guidelines para os demais pontos não comentados: metadados, segurança, compatibilidade, desativação de endpoints (como se traduz deprecation para pt-br?), performance, semântica das operações, cabeçalhos utilizados, etc.
Referências (infelizmente não conheço muito material em português)
Foi a primeira coisa que notei quando acessei o projeto, o versionamento na uri.
Estou de acordo com @otaciliolacerda, que colocou muito bem a proposta. Penso que a parte de remover o /api da URI já é até uma outra questão (na qual refleti, e parece fazer sentido tbm), que pode ser discutido em outra issue.
Olá. Acabei de conhecer o projeto e vi que já houve uma discussão sobre versionamento #12 que levou ao PR #25. Apesar de não existir uma forma correta de se fazer versionamento[1], gostaria de propor um modelo diferente que acho que seria mais vantajoso para esse projeto.
Contexto
Levando em conta que esse projeto criará uma API pública que potencialmente será utilizada por diversos clientes, acredito que é de extrema importância manter o processo de desenvolvimento o mais eficiente possível. Em minha experiência,
resource versioning
ouglobal uri versioning
adicionam algumas complexidades no desenvolvimento da API que acabam desacelerando a sua evolução:URI versioning
tira um pouco o charme de uma REST(ful) API já que não considero a versão um recurso ou sub-recurso. Lembrando que o pilar de uma REST API são os recursos e as operações que posso fazer nos mesmos.Proposta
Manter a URI consistente (sem versão) e utilizar
content negotiation
(utilizandoAccepts
eContent-Type
headers) para negociar qual conteúdo o cliente precisa. Em outras palavras, negociar a versão. Na prática a API evoluiria mantendo compatibilidade com as versões anteriores e os endpoints seriam os mesmos. Essa abordagem é utilizada no ambiente empresarial[2 e 3].Mas enfim, como seria isso na prática?
Antes:
Depois:
Guidelines
Considerando o Pull Request #101 e Issue #14 , teríamos os seguintes guidelines:
Usar semantic versioning v2
OpenAPI permite adicionar a versão em
#/info/version
(recomendo não usar as regras9
e10
). Exemplo:Apesar de não ter um impacto direto no funcionamento da API, esses metadados dão visibilidade e informações sobre a API para os clientes.
Usar
media type versioning
Versionamento baseado em negociação de conteúdo reduz o acoplamento e facilita a evolução da API. A versão (ou conteúdo) são negociados usando o cabeçalho
Content-Type
eAccept
do protocolo HTTP. Por exemplo:application/brasil.cep+json;version=2
. Para manter compatibilidade, cadabreaking change
(major release
) cria um novo tipo (media type
). Assim, os recursos (URI) e a semântica das operações são mantidas enquanto o versionamento é limitado ao tipo de conteúdo.Teríamos as seguintes regras:
media types
personalizados para versões diferentes. No jargão desemantic release
seria criar um novomedia type
quando tivermos ummajor
release. Enquanto não tivermos nenhuma mudança de versão é melhor se manter utilizando o padrão:application/json
request
eresponse
para dar visibilidadeContent-Type
no cabeçalhoVary
para permitir cache de versões diferentes em qualquer proxy que esteja no caminho:Formato / esquema:
custom-media-type
é o recurso. Exemplo:brasil.cep
version
é a versão. Exemplo:2
Exemplo
Suponha que o cliente queira apenas a nova versão:
Um servidor deve responder, assim como um cliente enviando uma requisição com conteúdo (
POST
por exemplo), usando o cabeçalhoContent-Type
do protocolo HTTP para declarar explicitamente qual versão do conteúdo esta sendo enviada:Próximos passos
Definir regras/guidelines para os demais pontos não comentados: metadados, segurança, compatibilidade, desativação de endpoints (como se traduz
deprecation
para pt-br?), performance, semântica das operações, cabeçalhos utilizados, etc.Referências (infelizmente não conheço muito material em português)
The text was updated successfully, but these errors were encountered: