0

TL;DR How to mix REST requests with some non-REST requests in SPA(frontend/backend)? Or might be I just get REST wrong?

We are planning new API for SPA and mobiles(plus probably some 3rd parties). There will be some requests which, I suppose, can't be covered by REST.

I am speaking mostly about requests which would make backend do something, which would modify state of document or give some additional info, based on document, but request itself is rather simplistic.

Here is really easy example. I want to add a comment to blog post. For example I might do it like this:

  1. Create comment. POST /comment
  2. Create connection between author and comment. POST /comment_author or PUT /comment with author_id.
  3. Create connection between comment and post. POST /comment_post or PUT /comment with post_id.

I also could do something like POST /comment with {author_id, post_id} which actually seems most logical here.

Everything did work, comment added to blogpost and associated with author.

Now customer wants to get statistics for his comment, like words stats and letters stats. As a part of request I pass comment_id. Backend might update comment with stats data, it might create separate entity and link it with comment or it might just send me those stats for this comment without saving.

So what would be the choices?

I can do something like:

  • GET/PUT /comment/:id/stats. For me it seems already hack, because as a result I don't want a document of type comment, but document of different type. As well as I don't send stats with request, I calculate them on backend so using PUT seems wrong.
  • POST/GET /comment_stats/:comment_id. Seems legit, but if I don't have a document/entity of type comment_stats, that would mean that I actually ask backend to create something, backend would reply me OK/Created, but actually I don't have this document somewhere saved.

So, while I understand REST != CRUD, I thought to use REST for simple CRUD and, for cases like that, to use RPC. So in RPC scenario I would just call POST comment.stats(comment_id)

My questions are what would be better choice in this situation, as well as are my thoughts about rest/rpc right?

Jevgeni Smirnov
  • 3,787
  • 5
  • 33
  • 50

1 Answers1

0

I would go with GET /comment_stats/:comment_id for proper separation of concerns, so that report code doesn't clutter the comment resource.

It doesn't matter if you don't actually have a comment_stats document, or how the data is represented on your backend. The REST API is just an abstraction over your backend.

In general, for any non-CRUD action like this, it's better anyway to create a new resource and deal with it as if it was a "machine": you send some instructions to the machine (via a GET or POST call). The machine executes it and then returns the result. A simple example would be an endpoint to convert images: you create an /image_converter end point (the machine), you POST an image to it, it converts it, and sends back the image. /image_converter would have no associated entity/document in the database but for the end user it's still a resource with a logical behavior.

laurent
  • 88,262
  • 77
  • 290
  • 428