O R em RESTO significa recurso
(O que não é verdade, porque representa Representational, mas é um bom truque lembrar a importância dos Recursos no REST).
Sobre PUT /groups/api/v1/groups/{group id}/status/activate
: você não está atualizando um "ativar". Um "ativar" não é uma coisa, é um verbo. Os verbos nunca são bons recursos. Uma regra prática : se a ação, um verbo, estiver na URL, provavelmente não é RESTful .
O que você está fazendo? Você está "adicionando", "removendo" ou "atualizando" uma ativação em um grupo ou, se preferir: manipulando um recurso "status" em um grupo. Pessoalmente, eu usaria "ativações" porque elas são menos ambíguas que o conceito "status": criar um status é ambíguo, criar uma ativação não é.
POST /groups/{group id}/activation
Cria (ou solicita a criação de) uma ativação.
PATCH /groups/{group id}/activation
Atualiza alguns detalhes de uma ativação existente. Como um grupo tem apenas uma ativação, sabemos a que recurso de ativação estamos nos referindo.
PUT /groups/{group id}/activation
Insere ou substitui a ativação antiga. Como um grupo tem apenas uma ativação, sabemos a que recurso de ativação estamos nos referindo.
DELETE /groups/{group id}/activation
Irá cancelar ou remover a ativação.
Esse padrão é útil quando a "ativação" de um Grupo tem efeitos colaterais, como pagamentos sendo feitos, e-mails sendo enviados etc. Somente POST e PATCH podem ter esses efeitos colaterais. Quando, por exemplo, a exclusão de uma ativação precisa, por exemplo, notificar os usuários por email, DELETE não é a escolha certa; nesse caso, você provavelmente vai querer criar um recurso de desativação : POST /groups/{group_id}/deactivation
.
É uma boa idéia seguir essas diretrizes, porque este contrato padrão deixa muito claro para seus clientes e todos os proxies e camadas entre o cliente e você, sabe quando é seguro tentar novamente e quando não. Digamos que o cliente esteja em algum lugar com wifi esquisito e seu usuário clique em "desativar", o que desencadeia um DELETE
: Se isso falhar, o cliente pode simplesmente tentar novamente, até obter 404, 200 ou qualquer outra coisa que possa manipular. Mas se dispara um, POST to deactivation
ele sabe que não deve tentar novamente: o POST implica isso.
Agora, qualquer cliente tem um contrato que, quando seguido, protege contra o envio de 42 e-mails "seu grupo foi desativado", simplesmente porque sua biblioteca HTTP continuava repetindo a chamada para o back-end.
Atualizando um Único Atributo: Use PATCH
PATCH /groups/{group id}
Caso você deseje atualizar um atributo. Por exemplo, o "status" pode ser um atributo nos Grupos que podem ser definidos. Um atributo como "status" geralmente é um bom candidato para limitar a uma lista de permissões de valores. Os exemplos usam algum esquema JSON indefinido:
PATCH /groups/{group id} { "attributes": { "status": "active" } }
response: 200 OK
PATCH /groups/{group id} { "attributes": { "status": "deleted" } }
response: 406 Not Acceptable
Substituindo o recurso, sem efeitos colaterais, use PUT.
PUT /groups/{group id}
Caso você deseje substituir um grupo inteiro. Isso não significa necessariamente que o servidor realmente crie um novo grupo e jogue fora o antigo, por exemplo, os IDs podem permanecer os mesmos. Mas para os clientes, é isso que PUT pode significar: o cliente deve assumir que ele recebe um item totalmente novo, com base na resposta do servidor.
O cliente deve, no caso de uma PUT
solicitação, sempre enviar o recurso inteiro, com todos os dados necessários para criar um novo item: geralmente os mesmos dados que uma criação do POST exigiria.
PUT /groups/{group id} { "attributes": { "status": "active" } }
response: 406 Not Acceptable
PUT /groups/{group id} { "attributes": { "name": .... etc. "status": "active" } }
response: 201 Created or 200 OK, depending on whether we made a new one.
Um requisito muito importante é que PUT
seja idempotente: se você precisar de efeitos colaterais ao atualizar um grupo (ou alterar uma ativação), deverá usá-lo PATCH
. Portanto, quando a atualização resultar, por exemplo, no envio de um email, não use PUT
.