0

I am creating a RESTful API where “entries” can be added, modified, and deleted. Each entry is automatically assigned an expiration date when it’s created and is automatically deleted unless renewed before that date. When an entry is renewed, it is simply given a later expiration date (by the server, the user cannot choose the expiration date).

My question is, what would be the RESTful way to expose the “renew” functionality?

A few possibilities that I thought of (though none of them really seem right):

  1. DELETE /api/entries/:id/expiration-date
  2. PATCH /api/entries/:id with "expirationDate": null in the (JSON) body
  3. PATCH /api/entries/:id with any or no body
  4. PUT /api/entries/:id (Essentially require the entry to be resubmitted)

Note: Currently the only intended consumers of the API will be my own client applications, but I may choose to make it public in the future.

Benjy Wiener
  • 1,085
  • 2
  • 9
  • 27
  • `PUT /api/entries/:id/expiration` with a new expiration date. – zerkms Mar 28 '19 at 02:53
  • @zerkms The expiration dates are chosen/set by the server. I updated the question to clarify. – Benjy Wiener Mar 28 '19 at 03:03
  • @BenjyWiener that doesn't matter, you should still use PUT. After all, you might make the new date configurable in the future. – Hong Ooi Mar 28 '19 at 04:11
  • @HongOoi Understood. As for the endpoint, would .../expiration be better than .../renew, since it appears more resource-like, or do you think it’s less clear what’s actually happening? – Benjy Wiener Mar 28 '19 at 04:15

2 Answers2

0

I would use

PUT /api/entries/id/renew

with the expiration date in the body (or with no expiry to use the default). Reason being that the expiry isn't really pertaining to the object itself; it's metadata associated with how the object is managed by your system.

Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
0

My question is, what would be the RESTful way to expose the “renew” functionality?

How would you do provide this functionality on a website?

You would presumably start by looking at the web page of the entry, via a GET request, that would load the current representation of the page into your local cache.ou

When the server judged that the entry was eligible for renewal, the web page would include some sort of hypermedia affordance for allowing the client to trigger the renew protocol. In this case, you probably don't want that affordance to have safe semantics, so it would be a form using the POST method. When the user submitted the form, the browser would create an HTTP request with the correct meta data and form data copied into the request body as described by the HTML processing rules; the request would be submitted to the URL specified in the form.action by the server.

Does the spelling of the URL matter to the user? Not really, the user just submits the form, the URL is just opaque data. Indirectly, it matters because of the way that cache invalidation semantics are defined -- if we intend that renewing should evict previously cached representations of the web page, then the post request should have the URL of the page itself.

Similarly, the web form doesn't need to be on the page - you could have a link to a form managed elsewhere, using different caching rules.

Do that, in a machine readable way, and you have yourself a REST API.

PUT and PATCH work the same basic way, except that request body is a description of the page itself. Download the HTML, make edits, then either PUT the new document in its entirety or compute a patch document and send that instead.

PUT and PATCH work really well for anemic domains - like document stores; it's more challenging to work with representations directly when you need to reverse engineer the change in order to work out the intent.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91