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.

...

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://totvs.com/api/users/10

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

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 utlizado para atualizar um objeto de forma incremental (ver RFC 5789)Também usado para atualizar uma entidade, mas diferente do PUT, recebe em seu corpo uma série de instruções ou o estado no qual o cliente gostaria que a entidade estivesse no final da operação. Deve ser tratado de forma atômica, 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áriosou todas as instruções foram completadas com sucesso ou deve retornar erro ao cliente.

PATH pode causar efeitos colaterais e portanto não é considerado seguto ou idenpotente.

Bloco de código
languagetext
POSTPATCH http://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.

O PATH pode recebi

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

...

VerboUsado paraTipo de operaçãoCódigo de sucessoDetalhes
POSTCriar uma entidadeSíncrona201Além do código de sucesso deve retornar a nova entidade criada.
PATCH ou PUTAtualizar uma entidadeSíncrona200Além do código de sucesso deve retornar 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:

Bloco de código
languagetext
POST https://totvs.com/api/users
{
 ...
}

DEVE retornar como responta:

Bloco de código
languagetext
202 Accepted
Location: https://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 utilizarem devem obedecer as regras descritas abaixo.

Como escolher o método adequado

Abaixo descrevemos algumas situações e o método adequado a ser usado.

GET

  • Quero retornar uma lista de usuários;
  • Quero retornar o usuário com o id x;
  • Quero retornar todas as permissões do usuário x;
  • Quero retornar todos os usuário maiores de idade;

PUT

  • Quero sobrescrever o usuário atual na base de dados usando os dados informados na requisição;
  • Quero alterar o estado do usuário para ativo independente de outras regras;

PATCH

  • Quero alterar o estado do usuário para inativo validando uma série de regras no servidor;
  • Quero alterar uma propriedade do usuário e para faze-lo o servidor irá alterar também propriedades de outras entidades;
  • Quero alterar a data de vencimento de uma conta mas apenas se for nos primeiros 15 dias do mês;

POST

  • Quero adicionar um novo usuário;
  • Quero executar uma ação ou serie de operações no usuário;

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 utilizarem devem obedecer as regras descritas abaixo.

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. Os endpoints devem suportar e respeitar estes valores em casos em que
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. Os 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-se retornar ao 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 de sucesso

Mensagens de sucesso devem ser retornadas para todos os códigos http 2xx e devem ter pelo menos o campo data (código http 2xxdevem) devem retornar diretamente a entidade que representa o objeto resultado da operação do endpoint. Ex:

Bloco de código
languagejs
{
GET  data: {}
}http://totvs.com.br/api/users/1

{
  name: "John",
  sobrenome: "Doe"
}

Âncora
ApiSuccessMsgColl
ApiSuccessMsgColl
Mensagens de sucesso para coleções

...

Bloco de código
languagejs
{
  data: {
    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 aqueles causados por dados inválidos 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 erro 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

...

Além destes campos obrigatórios é possível retornar campos opcionais e para diferenciá-los deve-se usar o prefixo totvs_. Ex.:

Bloco de código
languagejs
{
  totvs_total: 100,
  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 aqueles causados por dados inválidos 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 erro 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 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.

Por exemplo, a entidade usuário possui propriedades que apontam para suas permissões, comunidades e detalhes e portanto estas devem estar retraídas:

Bloco de código
languagejs
GET https://totvs.com/api/users/10


{

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.

Por exemplo, a entidade usuário possui propriedades que apontam para suas permissões, comunidades e detalhes e portanto estas devem estar retraídas:

Bloco de código
languagejs
GET https://totvs.com/api/users/10


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

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.

...

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

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

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://totvs.com/api/users/10?expand=communities.permissions

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

    }
}
}


Informações
titlelimites

A API deve suportar a expansão de até dois níveis de propriedade de retorno, ex: prop1.prop2.prop3.

Nos casos em que o objeto tenha uma sub coleção o numero máximo de registros dessa coleção não deve ultrapassar 20 registros. Se houver a necessidade de retornar mais itens deve-se considerar criar um endpoint especifico para retornar a coleção com suporte a filtro, ordenação, etc.


Versionamento


As APIs devem ser versionadas sempre que alguma alteração quebrar o contrato entre o usuário e a plataforma, a versão deve estar presente na URI e deve estar no forma v{major.minor}.

...