Páginas filhas
  • Guia de implementacao das APIs TOTVS

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Índice
maxLevel4
outlinetrue
exclude.*ndice
stylenone

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 incluindo:

...

Nota
titleAtenção

Atente-se para esta documentação. Para garantir um bom desenvolvimento de APIs publicas ou privadas, é imprescindível que os passos a seguir sejam respeitados.

Termos e Nomenclaturas

 

Os termos DEVE deve, NÃO DEVEnão deve, REQUERIDOrequerido, PODE pode, NÃO PODE não pode, RECOMENDADO recomendado, OPCIONAL opcional devem ser interpretados como descritos no padrão RFC-2119.

...

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

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.

...

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:

...

  • Identificador da entidade definido como parâmetro e não como caminho (na url)
    • https://fluig.totvs.com/api/document/permissions?documentId={id}

 

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

 

Informações
titleFique atento!

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/

...

  • O valor do parâmetro page deve ser um valor numérico (maior que zero) representando a página solicitada;
  • O parâmetro page é opcional e na sua ausência deve ser considerado o valor 1;
  • O valor do parâmetro pageSize deve ser um valor numérico (maior que zero) representando o total de registros retornados na consulta;
  • O parâmetro pageSize é opcional e na sua ausência deve ser considerado o valor 20;

...

  • A resposta de uma requisição com paginação deve retornar um campo indicando se existe uma próxima página disponível conforme descrito na mensagem de sucesso de lista e esse campo deve ter o nome hasNext.

 Por exemplo, a seguinte requisição deve retornar a terceira página de registros (dos registros 31 à 40 inclusive) de usuários:

Bloco de código
languagetext
GET https://fluig.totvs.com.br/api/users?page=4&pageSize=10

Métodos suportados

 

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

...

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:

Bloco de código
languagetext
POST http://fluig.totvs.com/api/users/10

{
  name: "",
  age: 20,
  ...
}
Informações
titleImportante

Caso o cliente NÃO 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 utlizado 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

Bloco de código
languagetext
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 sejam mantidas.

Não
OPTIONSDeve retornar pelo menos o campo Allow no cabeçalho da resposta listando os verbos suportados pelo endpoint.Sim

...

Cabeçalhos customizados não devem ser devem ser utilizados para representar qualquer estado, valor ou ação sobre a entidade representada pela url. Isso quer dizer que cabeçalhos não devem ter relação com o cliente do endpoint (mobile, desktop, etc), url, corpo da mensagem, corpo da resposta ou parâmetros da url. O protocolo HTTP oferece uma série de cabeçalhos para quase todas as situações e estas sempre tem precedência a um cabeçalho customizado.

...

Bloco de código
languagejs
{
    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"
}

 

  • O campo code deve identificar unicamente o erro na documentação da API;

Informações

Todos os códigos de error devem estar mapeados e listados na documentação da API.

  • O campo helpUrl deve apontar diretamente para documentação do erro na API;

...

Mensagens de sucesso

Mensagens de sucesso devem ser retornadas para todos os códigos http 2xx e devem ter pelo menos o campo content que representa o objeto resultado da operação do endpoint. Ex:

...

Bloco de código
languagejs
{
  content: {
    hasNext: true,
    items: [
      {},
      {},
      ...
    ]
  }
}

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 são aqueles causados por dados inválidos na nas requisições ou intencionalmente lançados do endpoint para o cliente. Todos os erros deste tipo devem obrigatoriamente retornar um código HTTP da família 4xx. Ex:

O cliente chamou um endpoint mas não estava devidamente autenticado. Deve ser retornado o código 401 - Unauthorized;

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;

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;

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;

O cliente chamou o endpoint passando no cabeçalho que aceita como retorno xml (Content-Type: text/xml) mas o serviço só consegue retornar JSON. Deve retornar o erro HTTP 406 - Not Acceptable.


Erros não esperados

São são os erros não tratados ou não intencionais. Esse tipo de erro devesempre retornar códigos HTTP da família 5xx. Ex:

O cliente chamou um endpoint mas o servidor não pode responder por que estava sobrecarregado. Deve retornar o código 503 - Service Unavailable;

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.

Parâmetros expansíveis


Todos os endpoints devem respeitar e suportar os campos expansíveis. E devem retornar os campos retraídos a menos que especificado na requisição através do parâmetro de url expand.

As entidades de retorno devem obedecer as regras:

Todas as propriedades que representam listas devem vir retraídas por padrão e devem usar a notação de lista vazia (Ex.: [] ).

Todas as propriedades que representam objetos devem vir retraídos e usar a notação de objeto sem propriedades. (Ex.: {} )

Ao retornar uma entidade, todas as suas propriedades que representam um objeto ou coleção devem vir retraídas e a entidade deve conter um campo adicional com o nome _expandables. Esse campo é uma lista com o nome de cada uma das propriedades que podem ser passadas na url para que o endpoint inclua na responta.

...

Caso o cliente queira expandir as propriedades, ele deve então fazer uma requisição informando o parâmetro expand na url e passando como valor uma lista separada por virgula (,) dos campos exatamente como descritos no campo _expandables.

info
Nota
titleAtenção

Apenas o primeiro nível das propriedades deve ser expandido, ou seja, se o objeto expandido tiver propriedades expansíveis elas devem vir retraídas.

...

Note que as propriedades do objeto expandido devem vir retraídas por padrão. O cliente pode solicitar que as propriedades dos objetos sejam expandidas separando as sub-propriedades com ponto (.). Usando o exemplo acima, o usuário gostaria de expandir as permissões das comunidades da entidade usuário:

 

Bloco de código
languagejs
GET https://fluig.totvs.com/api/users/10?expand=communities.permissions

{
  _expandables: ["permissions", "detailedInformation"],
  id: 10,
  name: "Usuário",
  age: 25,
  permissions: [],
  communities: [{
    name: "Vendas",
    photoUrl: "https://fluig.totvs.com/communities/1/photo",
    permissions: {
      isAdmin: true,
      canView: true
    }  
  }, {
    name: "Outra comunidade",
    photoUrl: "https://fluig.totvs.com/communities/2/photo",
    permissions: {
      isAdmin: true,
      canView: true
    }  
  }],
  detailedInformation: {},
  ...
}


Versionamento

API interna deve seguir esse padrão, mas é independe do versionamento. Deve estar documentado (tecnica) para as novas.

Validar como passar a versão URL ou header. Testar com o Paulo.

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

Documentação


Todas os métodos, parâmetros, códigos de erro e mensagens de requisição e retorno da API publica devem estar documentadas na página de documentação do fluig. Além disso deve ser gerado um documento SWAGGER com as definições da API.