Estou procurando uma maneira de agrupar APIs em torno de funções padrão em meus aplicativos Web, bancos de dados e CMSs baseados em PHP.
Eu olhei em volta e encontrei vários frameworks "esqueletos". Além das respostas na minha pergunta, há o Tonic , um framework REST que eu gosto porque é muito leve.
Gosto mais do REST por sua simplicidade e gostaria de criar uma arquitetura de API baseada nela. Estou tentando entender os princípios básicos e ainda não o compreendi completamente. Portanto, uma série de perguntas.
1. Estou entendendo certo?
Digamos que eu tenha um recurso "usuários". Eu poderia configurar vários URIs assim:
/api/users when called with GET, lists users
/api/users when called with POST, creates user record
/api/users/1 when called with GET, shows user record
when called with PUT, updates user record
when called with DELETE, deletes user record
essa é uma representação correta de uma arquitetura RESTful até agora?
2. preciso de mais verbos
Criar, Atualizar e Excluir pode ser suficiente em teoria, mas na prática precisarei de muito mais verbos. Sei que são coisas que podem ser incorporadas a uma solicitação de atualização, mas são ações específicas que podem ter códigos de retorno específicos e eu não gostaria de jogá-las todas em uma única ação.
Alguns que vêm à mente no exemplo do usuário são:
activate_login
deactivate_login
change_password
add_credit
como eu expressaria ações como as de uma arquitetura de URL RESTful?
Meu instinto seria fazer uma chamada GET para um URL como
/api/users/1/activate_login
e espere um código de status de volta.
Isso se desvia da idéia de usar verbos HTTP, no entanto. O que você acha?
3. Como retornar mensagens e códigos de erro
Uma grande parte da beleza do REST deriva do uso de métodos HTTP padrão. Em caso de erro, emito um cabeçalho com um código de status de erro 3xx, 4xx ou 5xx. Para uma descrição detalhada do erro, posso usar o corpo (certo?). Por enquanto, tudo bem. Mas qual seria a maneira de transmitir um código de erro proprietário mais detalhado na descrição do que deu errado (por exemplo, "falha ao conectar ao banco de dados" ou "login do banco de dados errado")? Se eu colocá-lo no corpo junto com a mensagem, tenho que analisá-lo posteriormente. Existe um cabeçalho padrão para esse tipo de coisa?
4. Como fazer autenticação
- Como seria uma autenticação baseada em chave de API, seguindo os princípios REST?
- Existem pontos fortes contra o uso de sessões ao autenticar um cliente REST, além de ser uma violação flagrante do princípio REST? :) (apenas brincando aqui, a autenticação baseada em sessão funcionaria bem com minha infraestrutura existente.)
fonte
Respostas:
Percebi essa pergunta alguns dias depois, mas sinto que posso acrescentar algumas dicas. Espero que isso possa ser útil para o seu empreendimento RESTful.
Ponto 1: Estou entendendo certo?
Você entendeu certo. Essa é uma representação correta de uma arquitetura RESTful. Você pode encontrar a seguinte matriz da Wikipedia muito útil para definir seus substantivos e verbos:
Ao lidar com um URI de coleção, como:
http://example.com/resources/
GET : Liste os membros da coleção, completos com seus URIs de membros para navegação adicional. Por exemplo, liste todos os carros à venda.
PUT : Significado definido como "substituir a coleção inteira por outra coleção".
POST : Crie uma nova entrada na coleção em que o ID é atribuído automaticamente pela coleção. O ID criado geralmente é incluído como parte dos dados retornados por esta operação.
DELETE : Significado definido como "excluir a coleção inteira".
Ao lidar com um URI de Membro, como:
http://example.com/resources/7HOU57Y
GET : Recupere uma representação do membro endereçado da coleção, expresso em um tipo MIME apropriado.
PUT : Atualize o membro endereçado da coleção ou crie-o com o ID especificado.
POST : trata o membro endereçado como uma coleção por si só e cria um novo subordinado.
DELETE : Exclua o membro endereçado da coleção.
Ponto 2: preciso de mais verbos
Em geral, quando você pensa que precisa de mais verbos, pode realmente significar que seus recursos precisam ser identificados novamente. Lembre-se de que no REST você está sempre atuando em um recurso ou em uma coleção de recursos. O que você escolhe como recurso é muito importante para sua definição de API.
Ativar / desativar logon : se você estiver criando uma nova sessão, poderá considerar "a sessão" como o recurso. Para criar uma nova sessão, use POST para
http://example.com/sessions/
com as credenciais no corpo. Para expirar, use PUT ou DELETE (talvez dependendo da intenção de manter um histórico de sessão) parahttp://example.com/sessions/SESSION_ID
.Alterar senha: desta vez, o recurso é "o usuário". Você precisaria de um PUT
http://example.com/users/USER_ID
com as senhas antigas e novas no corpo. Você está atuando no recurso "o usuário" e uma senha de alteração é simplesmente uma solicitação de atualização. É bastante semelhante à instrução UPDATE em um banco de dados relacional.Isso vai contra um princípio REST muito básico: o uso correto de verbos HTTP. Qualquer solicitação GET nunca deve causar nenhum efeito colateral.
Por exemplo, uma solicitação GET nunca deve criar uma sessão no banco de dados, retornar um cookie com um novo ID da sessão ou deixar qualquer resíduo no servidor. O verbo GET é como a instrução SELECT em um mecanismo de banco de dados. Lembre-se de que a resposta a qualquer solicitação com o verbo GET deve ser capaz de armazenar em cache quando solicitada com os mesmos parâmetros, assim como quando você solicita uma página da web estática.
Ponto 3: Como retornar mensagens e códigos de erro
Considere os códigos de status HTTP 4xx ou 5xx como categorias de erro. Você pode elaborar o erro no corpo.
Falha ao conectar-se ao banco de dados: / Logon incorreto no banco de dados : Em geral, você deve usar um erro 500 para esses tipos de erros. Este é um erro do lado do servidor. O cliente não fez nada de errado. 500 erros são normalmente considerados "repetíveis". ou seja, o cliente pode tentar novamente a mesma solicitação exata e esperar que seja bem-sucedido assim que os problemas do servidor forem resolvidos. Especifique os detalhes no corpo, para que o cliente possa fornecer algum contexto para nós, seres humanos.
A outra categoria de erros seria a família 4xx, que geralmente indica que o cliente fez algo errado. Em particular, essa categoria de erros normalmente indica ao cliente que não há necessidade de repetir a solicitação como está, porque continuará a falhar permanentemente. ou seja, o cliente precisa alterar alguma coisa antes de tentar novamente esta solicitação. Por exemplo, os erros "Recurso não encontrado" (HTTP 404) ou "Solicitação malformada" (HTTP 400) se enquadram nessa categoria.
Ponto 4: Como fazer autenticação
Conforme apontado no ponto 1, em vez de autenticar um usuário, convém pensar em criar uma sessão. Você receberá uma nova "ID da sessão", juntamente com o código de status HTTP apropriado (200: acesso concedido ou 403: acesso negado).
Você então perguntará ao servidor RESTful: "Você pode me OBTER o recurso para este ID da sessão?".
Não há modo autenticado - o REST é sem estado: você cria uma sessão, solicita ao servidor que forneça recursos usando esse ID de sessão como parâmetro e, ao sair, você interrompe ou expira a sessão.
fonte
PUT
para alterar uma senha provavelmente está incorreto;PUT
requer todo o recurso, portanto, você deverá enviar todos os atributos do usuário para cumprir com HTTP (e, portanto, com HATEOAS REST). Em vez disso, basta alterar a senha que se deve usarPATCH
ouPOST
.Simplificando, você está fazendo isso completamente ao contrário.
Você não deve abordar isso a partir de quais URLs deve usar. Os URLs virão efetivamente "de graça" quando você decidir quais recursos são necessários para o seu sistema E como os representará, e as interações entre os recursos e o estado do aplicativo.
Para citar Roy Fielding
As pessoas sempre começam com os URIs e pensam que essa é a solução e, em seguida, tendem a perder um conceito-chave na arquitetura REST, notadamente, como citado acima: "A falha aqui implica que informações fora de banda estão gerando interação em vez de hipertexto. "
Para ser honesto, muitos veem vários URIs e alguns GETs, PUTs e POSTs e acham que o REST é fácil. REST não é fácil. RPC sobre HTTP é fácil, mover blobs de dados para frente e para trás em proxy através de cargas úteis de HTTP é fácil. O REST, no entanto, vai além disso. O REST é independente de protocolo. O HTTP é muito popular e apto para sistemas REST.
O REST vive nos tipos de mídia, em suas definições e em como o aplicativo direciona as ações disponíveis para esses recursos via hipertexto (links, efetivamente).
Há uma visão diferente sobre os tipos de mídia nos sistemas REST. Alguns preferem cargas úteis específicas do aplicativo, enquanto outros gostam de elevar os tipos de mídia existentes para funções apropriadas para o aplicativo. Por exemplo, por um lado, você tem esquemas XML específicos criados para o seu aplicativo, em vez de usar algo como XHTML como sua representação, talvez por meio de microformatos e outros mecanismos.
Ambas as abordagens têm seu lugar, eu acho, o XHTML funcionando muito bem em cenários que se sobrepõem tanto à web orientada por humanos quanto à orientada por máquina, enquanto os tipos de dados anteriores e mais específicos me parecem melhores facilitam as interações máquina a máquina. Acho que a melhoria dos formatos de commodities pode dificultar a negociação de conteúdo. "application / xml + yourresource" é muito mais específico como tipo de mídia do que "application / xhtml + xml", pois o último pode ser aplicado a muitas cargas úteis que podem ou não ser algo em que um cliente de máquina está realmente interessado, nem pode determinar sem introspecção.
No entanto, o XHTML funciona muito bem (obviamente) na web humana, onde os navegadores e a renderização são muito importantes.
Você aplicativo irá guiá-lo nesses tipos de decisões.
Parte do processo de criação de um sistema REST é descobrir os recursos de primeira classe em seu sistema, juntamente com os recursos de suporte derivativos necessários para suportar as operações nos recursos primários. Depois que os recursos são descobertos, a representação desses recursos, bem como os diagramas de estado que mostram o fluxo de recursos via hipertexto nas representações, são o próximo desafio.
Lembre-se de que cada representação de um recurso, em um sistema de hipertexto, combina a representação real do recurso e as transições de estado disponíveis para o recurso. Considere cada recurso como um nó em um gráfico, com os links sendo as linhas que deixam esse nó para outros estados. Esses links informam aos clientes não apenas o que pode ser feito, mas o que é necessário para que eles sejam feitos (como um bom link combina o URI e o tipo de mídia necessário).
Por exemplo, você pode ter:
Sua documentação falará sobre o campo rel chamado "usuários" e o tipo de mídia de "application / xml + youruser".
Esses links podem parecer redundantes, eles estão todos falando com o mesmo URI, basicamente. Mas eles não são.
Isso ocorre porque, na relação "usuários", esse link está falando sobre a coleção de usuários e você pode usar a interface uniforme para trabalhar com a coleção (GET para recuperar todos eles, DELETE para excluir todos eles etc.)
Se você POSTAR para este URL, precisará passar um documento "application / xml + usercollection", que provavelmente conterá apenas uma única instância do usuário no documento, para que você possa adicionar o usuário ou talvez não adicionar várias em uma vez. Talvez sua documentação sugira que você possa simplesmente passar um único tipo de usuário, em vez da coleção.
Você pode ver o que o aplicativo requer para realizar uma pesquisa, conforme definido pelo link "search" e seu tipo de mídia. A documentação para o tipo de mídia de pesquisa informará como isso se comporta e o que esperar como resultados.
O ponto principal aqui, porém, é que os próprios URIs são basicamente sem importância. O aplicativo está no controle dos URIs, não dos clientes. Além de alguns 'pontos de entrada', seus clientes devem confiar nos URIs fornecidos pelo aplicativo para seu trabalho.
O cliente precisa saber como manipular e interpretar os tipos de mídia, mas não precisa se preocupar para onde vai.
Esses dois links são semanticamente idênticos aos olhos dos clientes:
Então, concentre-se em seus recursos. Concentre-se nas transições de estado no aplicativo e em como isso é melhor alcançado.
fonte
re 1 : Parece bom até agora. Lembre-se de retornar o URI do usuário recém-criado em um cabeçalho "Local:" como parte da resposta ao POST, junto com o código de status "201 Criado".
re 2: A ativação via GET é uma má ideia, e incluir o verbo no URI é um cheiro de design. Você pode considerar devolver um formulário em um GET. Em um aplicativo Web, esse seria um formulário HTML com um botão de envio; no caso de uso da API, convém retornar uma representação que contenha um URI para PUT para ativar a conta. Obviamente, você também pode incluir esse URI na resposta do POST para / users. O uso de PUT garantirá que sua solicitação seja idempotente, ou seja, poderá ser enviada novamente com segurança se o cliente não tiver certeza do sucesso. Em geral, pense em quais recursos você pode transformar seus verbos (tipo de "substantivo dos verbos"). Pergunte a si mesmo com qual método sua ação específica está mais alinhada. Por exemplo, change_password -> PUT; desativar -> provavelmente DELETE; add_credit -> possivelmente POST ou PUT.
3. Não invente novos códigos de status, a menos que você acredite que sejam tão genéricos que merecem ser padronizados globalmente. Tente usar o código de status mais apropriado disponível (leia sobre todos eles na RFC 2616). Inclua informações adicionais no corpo da resposta. Se você realmente tem certeza de que deseja inventar um novo código de status, pense novamente; se você ainda acredita, escolha pelo menos a categoria correta (1xx -> OK, 2xx -> informativo, 3xx -> redirecionamento; 4xx-> erro do cliente, 5xx -> erro do servidor). Eu mencionei que inventar novos códigos de status é uma má idéia?
4. Se for possível, use a estrutura de autenticação incorporada no HTTP. Veja como o Google faz autenticação no GData. Em geral, não coloque chaves de API em seus URIs. Tente evitar sessões para aprimorar a escalabilidade e dar suporte ao armazenamento em cache - se a resposta a uma solicitação diferir por causa de algo que já havia acontecido antes, você normalmente está vinculado a uma instância de processo do servidor específica. É muito melhor transformar o estado da sessão em um estado cliente (por exemplo, torná-lo parte de solicitações subsequentes) ou explicitar transformando-o em estado de recurso (servidor), ou seja, fornecer seu próprio URI.
fonte
1. Você tem a idéia certa sobre como projetar seus recursos, IMHO. Eu não mudaria nada.
2. Em vez de tentar estender o HTTP com mais verbos, considere a que seus verbos propostos podem ser reduzidos em termos de métodos e recursos básicos de HTTP. Por exemplo, em vez de um
activate_login
verbo, você pode configurar recursos como: o/api/users/1/login/active
que é um booleano simples. Para ativar um logon, apenasPUT
um documento que diz 'true' ou 1 ou o que for. Para desativar,PUT
um documento que está vazio ou diz 0 ou falso.Da mesma forma, para alterar ou definir senhas, basta fazer
PUT
s para/api/users/1/password
.Sempre que você precisar adicionar algo (como um crédito), pense em termos de
POST
s. Por exemplo, você pode fazer umPOST
para um recurso como/api/users/1/credits
um corpo que contém o número de créditos a serem adicionados. UmPUT
no mesmo recurso pode ser usado para substituir o valor em vez de adicionar. UmPOST
com um número negativo no corpo subtrairia, e assim por diante.3. Aconselho fortemente a não estender os códigos de status HTTP básicos. Se você não encontrar um que corresponda exatamente à sua situação, escolha o mais próximo e insira os detalhes do erro no corpo da resposta. Além disso, lembre-se de que os cabeçalhos HTTP são extensíveis; seu aplicativo pode definir todos os cabeçalhos personalizados que você desejar. Um aplicativo em que trabalhei, por exemplo, poderia retornar um
404 Not Found
sob várias circunstâncias. Em vez de fazer o cliente analisar o corpo da resposta pelo motivo, acabamos de adicionar um novo cabeçalhoX-Status-Extended
, que continha nossas extensões de código de status proprietário. Então você pode ver uma resposta como:Dessa forma, um cliente HTTP, como um navegador da web, ainda saberá o que fazer com o código 404 comum, e um cliente HTTP mais sofisticado pode optar por procurar no
X-Status-Extended
cabeçalho informações mais específicas.4. Para autenticação, eu recomendo usar a autenticação HTTP, se puder. Mas IMHO não há nada de errado em usar a autenticação baseada em cookies, se isso for mais fácil para você.
fonte
Noções básicas de REST
O REST possui uma restrição de interface uniforme, que indica que o cliente REST deve confiar nos padrões em vez de nos detalhes específicos do aplicativo do serviço REST real, para que o cliente REST não sofra alterações menores e provavelmente será reutilizável.
Portanto, há um contrato entre o cliente REST e o serviço REST. Se você usar HTTP como o protocolo subjacente, os seguintes padrões farão parte do contrato:
O REST possui uma restrição sem estado, que declara que a comunicação entre o serviço REST e o cliente deve ser sem estado. Isso significa que o serviço REST não pode manter os estados do cliente; portanto, você não pode ter um armazenamento de sessão no servidor. Você precisa autenticar cada solicitação. Portanto, por exemplo, a autenticação básica HTTP (parte do padrão HTTP) está correta, porque envia o nome de usuário e a senha a cada solicitação.
Para responder suas perguntas
Sim, pode ser.
Apenas para mencionar, os clientes não se preocupam com a estrutura do IRI, eles se preocupam com a semântica, porque seguem links com atributos de relações de link ou dados vinculados (RDF).
A única coisa importante sobre os IRIs é que um único IRI deve identificar apenas um único recurso. É permitido que um único recurso, como um usuário, tenha muitos IRIs diferentes.
É bem simples porque usamos IRIs legais
/users/123/password
; é muito mais fácil escrever a lógica de roteamento no servidor quando você entender o IRI simplesmente lendo-o.Você tem mais verbos, como PUT, PATCH, OPTIONS e muito mais, mas não precisa de mais ... Em vez de adicionar novos verbos, você precisa aprender como adicionar novos recursos.
activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}
(O logon não faz sentido da perspectiva REST, devido à restrição sem estado.)
Seus usuários não se importam com a razão da existência do problema. Eles querem saber apenas se há sucesso ou erro e, provavelmente, uma mensagem de erro que eles possam entender, por exemplo: "Desculpe, mas não conseguimos salvar sua postagem.", Etc ...
Os cabeçalhos de status HTTP são os cabeçalhos padrão. Tudo o resto deve estar no corpo, eu acho. Um único cabeçalho não é suficiente para descrever, por exemplo, mensagens de erro multilíngues detalhadas.
A restrição sem estado (junto com o cache e as restrições do sistema em camadas) garante que o serviço seja dimensionado bem. Você certamente não deseja manter milhões de sessões no servidor, quando pode fazer o mesmo nos clientes ...
O cliente de terceiros obtém um token de acesso se o usuário conceder acesso a ele usando o cliente principal. Depois disso, o cliente terceirizado envia o token de acesso a cada solicitação. Existem soluções mais complicadas, por exemplo, você pode assinar todas as solicitações etc. Para obter mais detalhes, consulte o manual do OAuth.
Literatura relacionada
dissertação de arquitetura de software baseada em rede de Roy Thomas Fielding (autor do REST)
2000, Universidade da Califórnia, Irvine
dissertação de dados vinculados de Markus Lanthaler (co-autor de JSON-LD e autor de Hydra)
2014, Universidade de Tecnologia de Graz, Áustria
fonte
Para os exemplos que você declarou, usaria o seguinte:
enable_login
POST /users/1/activation
deactivate_login
DELETE /users/1/activation
mudar senha
PUT /passwords
(isso pressupõe que o usuário esteja autenticado)adicionar crédito
POST /credits
(isso pressupõe que o usuário esteja autenticado)Para erros, você retornaria o erro no corpo no formato em que você recebeu a solicitação, portanto, se você receber:
DELETE /users/1.xml
Você enviaria a resposta de volta em XML, o mesmo seria para JSON etc ...
Para autenticação, você deve usar autenticação http.
fonte
create
como parte do URI (lembre-se de que os URIs devem ser substantivos e os métodos HTTP devem ser verbos que operam nesses substantivos.) Em vez disso, eu teria um recurso como o/users/1/active
qual pode ser um booleano simples e pode ser definido colocando 1 ou 0 nesse recurso.activation
no URI, a menos que você manipule e gerencie explicitamente um recurso com o nome de/users/1/activation
. O que faz um GET nisso? O que um PUT faz? Parece-me que você está verbalizando o URI. Além disso, quanto à negociação de tipo de conteúdo, geralmente é melhor deixar de fora o URI e inseri-lo em cabeçalhosAccept
.fonte
Eu sugeriria (como primeira passagem) que
PUT
só deve ser usado para atualizar entidades existentes.POST
deve ser usado para criar novos. ienão parece certo para mim. O restante da sua primeira seção (uso de verbo) parece lógico, no entanto.
fonte
Detalhado, mas copiado da especificação do método HTTP 1.1 em http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
9.3 GET
O método GET significa recuperar qualquer informação (na forma de uma entidade) identificada pelo Request-URI. Se o Request-URI se referir a um processo de produção de dados, são os dados produzidos que devem ser retornados como a entidade na resposta e não o texto de origem do processo, a menos que esse texto seja a saída do processo.
A semântica do método GET muda para um "GET condicional" se a mensagem de solicitação incluir um campo de cabeçalho If-Modified-Since, If-Modified-Since, If-Match, If-None-Match ou If-Range. Um método GET condicional solicita que a entidade seja transferida apenas nas circunstâncias descritas pelos campos de cabeçalho condicional. O método GET condicional visa reduzir o uso desnecessário da rede, permitindo que as entidades em cache sejam atualizadas sem exigir várias solicitações ou transferir dados já mantidos pelo cliente.
A semântica do método GET muda para um "GET parcial" se a mensagem de solicitação incluir um campo de cabeçalho Range. Um GET parcial solicita que apenas parte da entidade seja transferida, conforme descrito na seção 14.35. O método GET parcial tem como objetivo reduzir o uso desnecessário da rede, permitindo que entidades parcialmente recuperadas sejam concluídas sem transferir dados já mantidos pelo cliente.
A resposta a uma solicitação GET é armazenável em cache se, e somente se, atender aos requisitos de cache HTTP descritos na seção 13.
Consulte a seção 15.1.3 para considerações de segurança quando usado para formulários.
9.5 POST
O método POST é usado para solicitar que o servidor de origem aceite a entidade incluída na solicitação como um novo subordinado do recurso identificado pelo Request-URI na linha de solicitação. O POST foi projetado para permitir um método uniforme para cobrir as seguintes funções:
A função real executada pelo método POST é determinada pelo servidor e geralmente depende do URI de solicitação. A entidade postada é subordinada a esse URI da mesma maneira que um arquivo é subordinado a um diretório que o contém, um artigo de notícias é subordinado a um grupo de notícias no qual é postado ou um registro é subordinado a um banco de dados.
A ação executada pelo método POST pode não resultar em um recurso que pode ser identificado por um URI. Nesse caso, 200 (OK) ou 204 (Sem conteúdo) é o status de resposta apropriado, dependendo de a resposta incluir ou não uma entidade que descreve o resultado.
Se um recurso foi criado no servidor de origem, a resposta DEVE ser 201 (criada) e conter uma entidade que descreva o status da solicitação e se refira ao novo recurso, e um cabeçalho de localização (consulte a seção 14.30).
As respostas a esse método não podem ser armazenadas em cache, a menos que a resposta inclua os campos de cabeçalho Cache-Control ou Expir apropriados. No entanto, a resposta 303 (Consulte Outro) pode ser usada para direcionar o agente do usuário para recuperar um recurso armazenável em cache.
Os pedidos POST DEVEM obedecer aos requisitos de transmissão de mensagens estabelecidos na seção 8.2.
Consulte a seção 15.1.3 para considerações de segurança.
9.6 PUT
O método PUT solicita que a entidade fechada seja armazenada no URI de solicitação fornecido. Se o pedido de URI refere-se a um recurso já existente, a entidade fechada deve ser considerada como uma versão modificada do que reside no servidor de origem. Se o Request-URI não apontar para um recurso existente e esse URI puder ser definido como um novo recurso pelo agente do usuário solicitante, o servidor de origem poderá criar o recurso com esse URI. Se um novo recurso for criado, o servidor de origem DEVE informar o agente do usuário através da resposta 201 (Criada). Se um recurso existente for modificado, os códigos de resposta 200 (OK) ou 204 (sem conteúdo) DEVEM ser enviados para indicar a conclusão bem-sucedida da solicitação. Se o recurso não puder ser criado ou modificado com o Request-URI, uma resposta de erro apropriada deve ser dada que reflete a natureza do problema. O destinatário da entidade NÃO DEVE ignorar nenhum cabeçalho Content- * (por exemplo, Content-Range) que ele não entende ou implementa e DEVE retornar uma resposta 501 (Não Implementada) nesses casos.
Se o pedido passa através de um cache e o Request-URI identifica uma ou mais entidades atualmente em cache, essas entradas devem ser tratadas como obsoletas. As respostas a este método não são armazenáveis em cache.
A diferença fundamental entre as solicitações POST e PUT é refletida no significado diferente do Request-URI. O URI em uma solicitação POST identifica o recurso que manipulará a entidade fechada. Esse recurso pode ser um processo de aceitação de dados, um gateway para outro protocolo ou uma entidade separada que aceita anotações. Por outro lado, o URI em uma solicitação PUT identifica a entidade incluída na solicitação - o agente do usuário sabe qual URI se destina e o servidor NÃO DEVE tentar aplicar a solicitação a algum outro recurso. Se o servidor desejar que a solicitação seja aplicada a um URI diferente,
DEVE enviar uma resposta 301 (movida permanentemente); o agente do usuário PODE então tomar sua própria decisão sobre se deve ou não redirecionar a solicitação.
Um único recurso pode ser identificado por muitos URIs diferentes. Por exemplo, um artigo pode ter um URI para identificar "a versão atual", que é separada do URI que identifica cada versão específica. Nesse caso, uma solicitação PUT em um URI geral pode resultar na definição de vários outros URIs pelo servidor de origem.
O HTTP / 1.1 não define como um método PUT afeta o estado de um servidor de origem.
Os pedidos de PUT DEVEM obedecer aos requisitos de transmissão de mensagens estabelecidos na seção 8.2.
A menos que especificado de outra forma para um cabeçalho de entidade específico, os cabeçalhos de entidade no pedido PUT DEVEM ser aplicados ao recurso criado ou modificado pelo PUT.
9.7 APAGAR
O método DELETE solicita que o servidor de origem exclua o recurso identificado pelo Request-URI. Este método pode ser substituído por intervenção humana (ou outros meios) no servidor de origem. Não é possível garantir ao cliente que a operação foi realizada, mesmo que o código de status retornado do servidor de origem indique que a ação foi concluída com êxito. No entanto, o servidor NÃO DEVE indicar sucesso, a menos que, no momento em que a resposta seja dada, pretenda excluir o recurso ou movê-lo para um local inacessível.
Uma resposta bem-sucedida DEVE ser 200 (OK) se a resposta incluir uma entidade que descreve o status, 202 (Aceito) se a ação ainda não foi promulgada ou 204 (Sem Conteúdo) se a ação foi promulgada, mas a resposta não incluir uma entidade.
Se o pedido passa através de um cache e o Request-URI identifica uma ou mais entidades atualmente em cache, essas entradas devem ser tratadas como obsoletas. As respostas a este método não são armazenáveis em cache.
fonte
Sobre os códigos de retorno REST: é errado misturar códigos de protocolo HTTP e resultados REST.
No entanto, vi muitas implementações misturando-as e muitos desenvolvedores podem não concordar comigo.
Os códigos de retorno HTTP estão relacionados a
HTTP Request
ele próprio. Uma chamada REST é feita usando uma solicitação do Hypertext Transfer Protocol e funciona em um nível mais baixo do que o próprio método REST invocado. REST é um conceito / abordagem e sua saída é um resultado comercial / lógico , enquanto o código de resultado HTTP é um transporte .Por exemplo, retornar "404 Não encontrado" quando você chama / users / é confuso, porque pode significar:
"403 Proibido / Acesso Negado" pode significar:
E a lista pode continuar com 'Erro do servidor 500 "(um erro HTTP do Apache / Nginx lançado ou um erro de restrição de negócios no REST) ou outros erros HTTP etc.
No código, é difícil entender qual foi o motivo da falha, uma falha HTTP (transporte) ou uma falha REST (lógica).
Se a solicitação HTTP foi fisicamente executada com sucesso, ela sempre deve retornar 200 códigos, independentemente dos registros encontrados ou não. Porque o recurso URI foi encontrado e foi tratado pelo servidor http. Sim, pode retornar um conjunto vazio. É possível receber uma página da web vazia com 200 como resultado http, certo?
Em vez disso, você pode retornar 200 códigos HTTP e simplesmente um JSON com uma matriz / objeto vazio, ou usar um sinalizador bool result / success para informar sobre o status da operação executada.
Além disso, alguns provedores de Internet podem interceptar suas solicitações e retornar um código http 404. Isso não significa que seus dados não foram encontrados, mas há algo errado no nível do transporte.
Do Wiki :
fonte