6

My app has an API endpoint GET /sessions/{id} which gets info about a session. This endpoint returns a lot of data, so we allow passing JSON in the request body to filter what fields etc. are requested. I know GET requests should not include request body, so I am trying to convert it to POST but not sure what to call the endpoint now:

  • POST /sessions/{id} (but this looks like it's modifying the session, which it doesn't do)
  • POST /session_info/{id} (to make it clear that we are just querying info)
  • POST /session/{id}/info

Example use:

GET /sessions/42

request body:

{'participants': ['jsmith', 'bjones'], 'participant_fields': ['dob', 'zip']}`

response:

{
    'id': 42, 
    'date': '2022-08-29', 
    'room': 15, 
    'participants': [
        {'id': 'jsmith', 'dob': '1985-01-06', 'zip': 04843},
        ...
    ],
    ...
}

(participants and participant_fields are optional; if omitted it will return all data about all participants.)

I know the filter params could be encoded as query string but I just think it's easier for my users to use JSON.

Any advice?

1
  • 1
    You can check out GraphQL for this kind of behaviour! Commented Aug 29, 2022 at 15:10

3 Answers 3

10

Since you are throwing REST out the window by using a POST to retrieve data, it does not matter what you call it. Choose a name that fits the use case, and don't worry about REST semantics.

Large filters that potentially exceed the length limits for a query string are a good example of cases where the semantics added by REST are no longer useful. Use a POST, give it a sensible name, and document this deviation from the convention. I'm sure your clients will understand and not care.

5
  • 3
    Using POST to "retrieve data" does not "throw REST out the window". You can POST queries without a problem. REST just says to have standardized semantics. In this case that's HTTP. And HTTP POST does not disallow this kind of usage. Specifically it does not require any server resources to change. I do agree with you that URI path names should be irrelevant to the client though, especially when using REST where clients should never ever have hardcoded URIs or parts of URIs in them anyway. Commented Aug 29, 2022 at 12:39
  • 1
    @RobertBräutigam: the intent of a POST is to modify a resource. If the client has no intent to modify a resource, but instead intends on retrieving a resource, then I would argue that you aren't following REST semantics -- and that's OK. Just get something working. I think the issue here is the intention of the request. Commented Aug 29, 2022 at 15:13
  • 2
  • 1
    POST can be used as "general purpose" for app-specific method calls: w3.org/2001/sw/wiki/REST just think at a regular POST - auth/login endpoint. login is not even the name of a resource, but an action you perform. Commented Aug 29, 2022 at 15:31
  • 3
    datatracker.ietf.org/doc/html/… is still an Internet-Draft. When/If it reaches Internet-Standard status, we should have a better alternative to POST. Commented Aug 29, 2022 at 15:47
3

What to name a POST endpoint that behaves like GET?

Anything you want, really - the machines don't care what spelling conventions that you use for your resource identifiers.

That said, the machines do care about whether two resource identifiers are the same. The URI is the primary key used in caching, and if you are using unsafe methods (like POST) then you need to be aware of the implications of cache invalidation.

Furthermore, you'll want to consider whether or not it makes sense to make the response to the POST itself cacheable (meaning that the response can be re-used in support of GET or HEAD requests).

From your description, it doesn't make sense, because different request bodies should produce different representations.

And you probably don't want the "narrowed" versions of the representations to invalidate previous cached copies of the "full" resource. So you want the URI that you use for the POST to be different.


Which different URI to use? Anything you like is fine. Using an identifier with an additional path segment will be a convenient choice if you want to use dot segments to refer to the identifier of the original resource.

GET /sessions/12345
POST /session/12345/info

But it would also be fine to use a resource with a completely different path

GET /sessions/12345
POST /sessions-info/12345

It really just comes down to choosing a spelling that makes life easier for a group of people that you care about (api developers? operators? your technical writers? pick someone).

0

In this cases, sometimes this is broken down into a POST and then a GET. POST the query parameters, they get saved and then a query key is returned. The use the query key to GET the results.

Then the REST semantics are preserved. But it is two trips.

Not the answer you're looking for? Browse other questions tagged or ask your own question.