Como vocês criam rotas que "executam ações" nas APIs de vocês?
Pra começar, um breve contexto:
Já vi sistemas por aí, onde as alterações de dados (inclusive as "ações") são feitas por uma única rota que utiliza o método PUT (ou PATCH).
Acredito que isso acontece porque em vários cursos online, é demonstrada a criação de uma aplicação ‘CRUD’ com 5 rotas (o que é ok para fins didáticos).
Exemplo, considerando uma API consumida pelo frontend, de um sistema de chats de mensagens (tipo o Whaticket):
POST /chats → cria um novo chat
GET /chats → retorna a lista de chats
GET /chats/:id → retorna um chat específico
PUT /chats/:id → altera um chat específico
DELETE /chats/:id → remove um chat específico
Até aqui parece tudo certo, né?
Mas agora imagina que os chats tem esses 2 campos:
→ 'status': que pode ter os valores: pending, assigned (em andamento) e closed
→ 'userId': indicando o usuário que está atendendo o chat
E que existem 3 botões/ações no sistema:
→ ‘finalizar um chat’
→ ‘começar a atender um chat’
→ ‘transferir um chat’
Se for mantida apenas a rota 'PUT /chats/:id', começa a surgir a necessidade de alguns IFs e condicionais, que podem se tornar difíceis de ler, entender e manter.
Por exemplo, o backend precisaria identificar que se o status estiver sendo alterado, e o novo status for ‘closed’, o chat está sendo finalizado, e realizar o fluxo necessário (por exemplo, o envio de uma mensagem de despedida).
Ele também precisaria identificar que se o userId estiver sendo alterado, o chat está sendo transferido, e também realizar o fluxo necessário (por exemplo, voltar o status do chat para ‘pending’ até que o novo usuário comece a atendê-lo).
E com isso, teríamos uma rota que faz várias coisas, de forma implícita e não tão clara, tendo várias responsabilidades e condicionais no código.
Ok, mas qual seria a solução?
Para rotas que realizam ações específicas em determinado registro, é comum o mercado no geral utilizar POST e o nome da ação.
Exemplo:
POST /chats/:id/transfer
POST /chats/:id/close
Ou em APIs de pagamentos, é comum algo como:
POST /payments/:id/refund (para estornar um pagamento)
POST /subscriptions/:id/cancel (para cancelar uma assinatura recorrente)
Dessa forma, o código fica mais separado e fácil de ler, entender e manter, pois cada rota do backend realiza uma única ação.
E também fica mais claro para o frontend qual requisição a ser feita para cada ação, sem precisar saber/enviar detalhes específicos de cada campo.
Fiquem à vontade pra deixar a opinião de vocês sobre esse assunto :)