APIs REST: cabeçalhos HTTP personalizados vs parâmetros de URL

96

Quando você usa cabeçalhos HTTP personalizados na parte da solicitação de uma API REST?

Exemplo:

Você usaria

GET /orders/view 
(custom HTTP header) CLIENT_ID: 23

ao invés de

GET /orders/view/client_id/23 or 
GET /orders/view/?client_id=23
Vasile Cotovanu
fonte

Respostas:

123

O URL indica o próprio recurso. Um "cliente" é um recurso que pode ser posta em prática, por isso deve ser parte do URL base: /orders/view/client/23.

Parâmetros são apenas isso, para parametrizar o acesso ao recurso. Isto vem especialmente em jogo com mensagens e pesquisas: /orders/find?q=blahblah&sort=foo. Há uma linha tênue entre parâmetros e sub-recursos: /orders/view/client/23/active versus /orders/view/client/23?show=active. Eu recomendo o estilo de sub-recurso e parâmetros de reserva para pesquisas.

Como cada ponto de extremidade representa uma transferência de estado (para destruir o mnemônico), cabeçalhos personalizados devem ser usados ​​apenas para coisas que não envolvam o nome do recurso (o url), o estado do recurso (o corpo) ou parâmetros diretamente afetando o recurso (parâmetros). Isso deixa metadados verdadeiros sobre a solicitação de cabeçalhos personalizados.

HTTP tem uma seleção muito ampla de cabeçalhos que cobrem quase tudo que você precisa. Onde eu vi cabeçalhos personalizados aparecerem em uma solicitação de sistema para sistema operando em nome de um usuário. O sistema proxy validará o usuário e adicionará " X-User: userid" aos cabeçalhos e usará as credenciais do sistema para atingir o endpoint. O sistema receptor valida se as credenciais do sistema estão autorizadas a agir em nome do usuário e, em seguida, valida se o usuário está autorizado a executar a ação.

Nialscorva
fonte
Obrigado por uma resposta tão abrangente! Você ainda usaria o X-User para uma API móvel onde o risco de ter um proxy maligno (que retira o cabeçalho) ainda é alto?
Vasile Cotovanu
1
Não, o uso do X-User que mencionei é em conexões de sistema para sistema em que o sistema está agindo em nome de terceiros. Por exemplo, o usuário U fala com o servidor A. O servidor A apresenta credenciais para o servidor B com um cabeçalho X-User para dizer "Use minhas credenciais para verificar se estou autorizado a executar esta ação em nome do usuário U." Isso surge em arquiteturas orientadas a serviços e, geralmente, você está usando HTTPS. Uma plataforma móvel deve quase sempre ser o próprio Usuário agindo e usar credenciais de primeira pessoa adequadas para a transação.
Nialscorva
7
O terceiro parágrafo é uma das respostas mais informativas que li no SO ;-)
Alistair77
1
@Nialscorva Ótima explicação! e se eu quiser que o usuário interaja com minha API por meio de um contêiner autorizado (como meu aplicativo móvel)? O que estou fazendo agora é que meu aplicativo móvel não está autorizado a executar nenhuma ação por conta própria e nem o usuário final. Ambas as credenciais devem estar presentes se o usuário estiver disposto a executar uma ação.
bolbol de
6

Os cabeçalhos personalizados têm as seguintes vantagens:

  • Pode ser lido facilmente por ferramentas / scripts de rede (autenticação, meta informações, ...)
  • Mantém os URLs livres de material de segurança (mais seguro, não em caches de navegador / proxy)
  • Mantém os urls mais limpos: permite um melhor armazenamento em cache dos recursos
Christophe Roussy
fonte
eles também podem ser removidos / filtrados silenciosamente por proxies
fusi
@fusi bom ponto ... aqui está um tópico sobre isso: stackoverflow.com/questions/20820572/…
Christophe Roussy
5

Eu só usaria um cabeçalho personalizado quando não houvesse outra maneira de passar informações por padrão ou convenção. Darren102 está explicando a maneira típica de passar esse valor. Sua Api será muito mais amigável usando padrões típicos em verso usando cabeçalhos personalizados. Isso não quer dizer que você não terá um caso para usá-los, apenas que eles devem ser o último recurso e algo ainda não tratado pela especificação HTTP.

processando
fonte
Concordo de todo o coração ... nunca reinvente a roda se houver uma maneira padrão de realizar uma tarefa.
Alessandro Santini
5

Quando você usa ... cabeçalhos HTTP na parte de solicitação de uma API REST?

Autenticação: GUIDs, autenticação básica, tokens personalizados, etc., por exemplo, Autenticação Básica com um token Guid para API REST em vez de nome de usuário / senha

Se você se envolver na passagem de tokens ou outras informações semelhantes à autenticação entre domínios cobertos por PCI-DSS ou outras regras de segurança, você também pode ter que enterrar parâmetros porque alguns regulamentos exigem explicitamente que elementos de autenticação fiquem fora de URLs que podem ser repetidamente reproduzidos (de históricos do navegador, logs de proxy, etc.).

user3038458
fonte
1

Não existe um padrão para REST, mas a forma aceita seria

GET /orders/view/23

Não usar os cabeçalhos personalizados e, portanto, o 23 after view assume ser o id, portanto, você teria uma função que recebe o id e, portanto, produz apenas essa informação.

darren102
fonte
1

Eu não usaria cabeçalhos personalizados, pois você não sabe se algum proxy os transmitirá. Com base em URL é o caminho a percorrer.

GET / orders / view / client / 23

Antony Scott
fonte
1
Eu também não recomendaria cabeçalhos personalizados, mas os proxies corrompidos não são o motivo. O proxy está quebrado, deve ser consertado.
Julian Reschke
1

Definitivamente OK:

GET /orders/view/client_id/23 or 
GET /orders/view/?client_id=23

Também ok:

GET /orders/view/23 or 

Eu também acho que isso seria bom:

POST /orders/view 
(custom HTTP header) CLIENT_ID: 23
paulsm4
fonte
A resposta POST completa REST deve ser um HTTP 303 com o cabeçalho Location definido como algo como "/ orders / view / 23".
Rich Remer
0

Você pode usar cabeçalhos personalizados para incluir mais informações sobre uma solicitação parcialmente processada, considerando que o envelope não é uma boa prática. Os cabeçalhos são seguros .

Anwar Husain
fonte