Índice

Introdução

Este documento define os padrões que devem ser adotados durante a implementação de novas APIs publicas ou privadas na plataforma do fluig incluido:

Comitê

Criamos um comitê interno, formado com um integrante de cada squad, para discutir e garantir a execução dos padrões definidos neste documento.

Cada um dos membros deve obrigatoriamente ser incluído no pull request de novas APIs publicas e cadas um deles é responsável por garantir a correta disseminação e implementação dentro de seu próprio time das APIs privadas.

 

SquadMembro
SDKMarcelo De Aguiar
Identity / PortalPaulo Roberto Francisco Junior
LMSDiego Lopes
BPMGustavo Martins De Souza
PAAS / FundaçãoVanei Anderson Heidemann
ECMAndre Felipe Joriatti
IntegraçãoDanilo Pacheco Martins

 

Nomenclaturas

Cliente: Qualquer aplicativo que faça uma requisição para um endpoint do fluig.

Mensagem: Conteúdo enviado no corpo de uma requisição ou resposta do servidor.

Endpoint: Representa um método ou entidade que pode ser acessado através de uma requisição ao servidor do fluig.

Verbo: Tipo de requisição usada para acessar um endpoint (GET, POST, PUT, HEAD, etc).

API: Grupo de endpoints

APIs Privadas são todas as APIs acessíveis apenas pelos times do fluig

APIs Publicas são todas as APIs que podem ser acessadas por clientes externos aos times de desenvolvimento do fluig.

 

Estrutura de URLs

Os caminhos definidos para cada endpoint devem ser de fácil leitura e significativos para o cliente para facilitar a sua descoberta e adoção. Os pontos abaixo DEVEM ser considerados ao criar uma URL:

 

Exemplo de URLs amigáveis:

Colocar exemplo de filtro e expansíveis

Exemplo de URLS NÃO amigaveis e que deve ser evitadas:

 

Apesar de o padrão definido no documento RFC 7230 da especificação do HTTP 1.1 não definir um tamanho maximo para a url nenhum endpoint do fluig deve ser identificado com uma url maior que 2000 caracteres para garantir que todos os navegares modernos sejam suportados

 

Mais informações sobre a escolha do valor máximo de caracteres pode ser consultada em:

http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers/417184#417184

https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/

 

Métodos suportados

Endpoints devem usar os métodos HTTP adequados e devem respeitar a idempotência da operação.

Na tabela abaixo serão listados os métodos que DEVEM ser suportados. Nem todos os endpoints devem suportar todos os métodos, mas os que usarem DEVEM respeitar a utilização conforme descrita.

MétodoDescriçãoIdempotente
GETRetorna o valor corrente do objeto.Sim
PUT

Sobrescreve o objeto quando aplicável. Por exemplo: O cliente gostaria de sobrescrever o usuário com novos valores:

POST http://fluig.totvs.com/api/users/10

{
  name: "",
  age: 20,
  ...
}

Caso o cliente NÃO informe alguma propriedade para ser atualizada está DEVE ser considerada nula. Está informação DEVE estar clara na documentação do método para que o cliente não há utilize inadvertidamente, ou pode-se optar por não implementá-la.

Sim
DELETEExclui o objeto.Sim
POSTCria um novo objeto ou submete um comando ao objeto.Não
HEADRetorna os metadados da requisição em casos em que o cliente não precisa do corpo das requisições do tipo GET.Sim
PATCH

PATH foi padronizado pelo IETF como o método usado para atualizar um objeto de forma incremental (ver RFC 5789), ou seja, apenas as propriedades informadas pelo cliente serão atualizadas. Por exemplo: O cliente gostaria de atualizar o nome do usuário e para isso vai usar o endpoint de atualização de usuários

POST http://fluig.totvs.com/api/users/10

{
  name: "Novo nome do usuário"
}

O servidor deverá implementar o serviço de modo que apenas o nome do usuário seja atualizado e todas as outras propriedades mantidas.

Não
OPTIONSRetorna informações sobre um endpoint e sobre as operações suportadas por ele; ver abaixo para mais detalhes.Sim

POST x PUT x PATCH

Deve-se atentar aos códigos de retorno para os tipos de operações definidos para usar estes métodos principalmente nos casos definidos abaixo:

VerboUsado paraTipo de operaçãoCódigo de sucessoDetalhes
POSTCriar uma entidadeSíncrona201Além do código de sucesso deve retorna a nova entidade criada.
PATCH ou PUTAtualizar uma entidadeSíncrona200Além do código de sucesso deve retorna a nova entidade atualizada.
POST, PATCH, PUTCriar ou atualizar entidadeAssíncrona202

O código 202 informa ao cliente que o serviço aceitou a requisição para processamento e que isso pode levar um tempo para concluir. Nesse caso o endpoint DEVE retornar o campo Location no cabeçalho da resposta apontando para onde a nova entidade poderá ser encontrada. Por exemplo, considere o endpoint de cadastro assíncrono de usuários:

POST https://fluig.totvs.com/api/users
{
 ...
}

DEVE retornar como responta:

202 Accepted
Location: https://fluig.totvs.com/api/users/10

 

 

Padrões de cabeçalhos de requisição

A utilização destes cabeçalhos não é obrigatória para todos os endpoints mas os que os usarem DEVEM obedecer as regras descritas aqui.

HeaderTipoDescrição
AuthorizationliteralCabeçalho usado para autorização das requisições
DatedataData e hora da requisição com base no calendário do cliente no formato estipulado em RFC 5322
Acceptenumerador de tipo de conteúdo

O tipo de conteúdo esperado para a resposta como por exemplo:

  • application/xml
  • text/xml
  • application/json
  • text/javascript

 

De acordo com os padrões HTTP, este valor é apenas uma dica para o servidor e as respostas PODEM retornar valores em formatos diferentes dos informados.

Accept-EncodingGzip, deflateEndpoints DEVEM suportar codificação GZIP e DEFLATE por padrão exceto em casos em que isso implique na performance.
Accept-Language"en", "es", "pt"Especifica o idioma preferencial da resposta. Endpoints DEVEM suportar e respeitar estes valores em casos em que uma mensagem é retornada ao usuário. Caso o idioma informado não seja suportado deve retornar no idioma padrão (pt).
Content-Typetipo de conteúdoTipo do conteúdo sendo passado na requisição. O endpoint DEVE respeitar esta informação na hora de interpretar a informação passada pelo cliente ou retornar um erro apropriado caso o valor não for suportado.
   

 

Mensagens

Durante a construção das mensagens que serão transmitidas entre o cliente e endpoint deve-se garantir a consistência entre nomes de propriedades e objetos quando os mesmo fizerem parte de um mesmo grupo ou assunto.

 

Mensagens de retorno do endpoint para o cliente devem obedecer a estrutura definida para mensagens de erro ou mensagens de sucesso

Mensagem de erro

Todos as respostas de erro (códigos HTTP 4xx e 5xx) devem retornar uma mensagem contendo obrigatoriamente os campos a seguir:

{
    code: "Código identificador do erro",
    helpUrl: "link para a documentação do error",
    message: "Literal no idioma da requisição descrevendo o erro para o cliente",
    detailedMessage: "Mensagem técnica e mais detalhada do erro"
}

 

Em alguns casos se faz necessário retornar mais campos do que os estipulados acima. Nestes casos a informação deve ser considerada opcional do ponto de vista do cliente, ou seja, o cliente não deve depender dela para o tratamento do erro.

 

Código 4xx versus 5xx

Dividimos os erros em duas categorias: Erros de negócio ou requisição e Erros não esperados.

Erros de negócio ou requisição são aqueles causados por dados inválidos na requisiçõe ou intencionalmente lançados do endpoint para o cliente. Todos os erros deste tipo devem obrigatoriamente retornar um código HTTP 4xx. Ex:

  1. O cliente chamou um endpoint mas não estava devidamente autenticado. Deve ser retornado o código 401 - Unauthorized
  2. O cliente chamou um endpoint mas mesmo estando autenticado não possui as permissões necessárias para efetuar a operação. Deve retornar o código 403 - Forbidden
  3. O cliente chamou o endpoint para buscar um usuário (Ex: /users/{id}) mas o usuário não existe. Deve ser retornado o código de erro 404 - Not found
  4. O cliente chamou o endpoint para efetuar alguma operação mas por alguma regra de negócio a operação não pode ser concluída e não existe um código de erro HTTP apropriado para descrevê-lo. Deve ser retornado o código de error 400 - Bad Request
  5. O cliente chamou o endpoint passando no cabeçalho que aceita como retorno xml (Content-Type: text/xml) mas o serviço consegue retornar JSON. Deve retornar o erro HTTP 406 - Not Acceptable
  6. O cliente chamou um endpoint para subir um documento mas o usuário logado passou o limite de espaço estipulado para seu perfil. Deve retornar o código 507 - Insufficiente Storage;

Erros não esperados são os erros não tratados ou não intencionais. Esse tipo de erro deve sempre retornar códigos HTTP 5xx. Ex:

  1. O cliente chamou um endpoint mas o servidor não pode responder por que estava sobrecarregado. Deve retornar o código 503 - Service Unavailable;
  2. O cliente chamou um endpoint para subir um documento mas não havia espaço em disco no servidor. Deve retornar o código 507 - Insufficiente Storage;

 

 

Dicas de como implmentar os métodos para tentar manter um padrão de implementação.