0

I'll try to make this as simple as possible, it may be sort of dumb question.

I'm rewriting an 7 years old web application (help desk software). It is required to make it a REST API to be consumed by different clients web browser and mobile app. Also required to keep the business logic as close as possible to the original which for now have been working well.

The current struggle about REST:

What I need is to update the a resource lets say /tickets/47321

If the status_id of the this resource is changed a record of this change need to be saved, both in the same DB transaction because it need to be all-or-nothing. this is how the original application worked and we would like to keep this behavior.

So question is:

Can I PUT to tickets/47321 the whole resource or partial state representation to update the resource residing in server and create the new record of the history change (if status_id is different) and return them both back to client as JSON:

 {
    ticket: {}, // new ticket state
    history: {} // the new created record of history change 
 }

This way the client can update the ticket and add the history to a list of history changes if there is any being return?

Alexandru Marculescu
  • 5,569
  • 6
  • 34
  • 50
David Lavieri
  • 1,060
  • 1
  • 8
  • 19
  • Yes, you can do this. In Java, some lightweight REST frameworks include Restlets and JAX-RS, and Spring is a good one on the heavier side. – Tim Biegeleisen Jul 05 '16 at 00:46
  • So is normal this behavior to occur in REST APIs? What about sending the partial representation on `PUT` and not the whole resource to update? – David Lavieri Jul 05 '16 at 00:55
  • Why would you want to send a partial representation? – Tim Biegeleisen Jul 05 '16 at 00:58
  • Thinking In case where I only need to change a maximum of 1~3 fields and not all. I know there is `PATCH` but it need to used differently, sending the instructions of how it should be modified instead of the state to update – David Lavieri Jul 05 '16 at 01:29

1 Answers1

0

Technically, yes, you can do this. However, it might not be as straightforward as simply returning 2 objects, side by side; looking at the Richardson Maturity Model (Level 1), one would expect to receive the same type of resource after calling (PUT) an api endpoint.

That being said, you could either embed the additional resource (append a history change to a ticket, following the Hypertext Application Language (HAL) proposed draft specification), or better yet (if you're aiming towards REST level 3), provide a link relationship, in conformity with the "Target IRI" defined in Web Linking specification (RFC 5988) from the ticket:

  • /api:history?ticketId=47321 would return all the history records belonging to that ticket, paged and sorted by created date, for example (and you can just select the latest)
  • /api:history?id=123 you would do some work on the server to ensure this points straight to the latest history record (related to that ticket id)

Regarding the partial update, looking at the RFC 6902 (which defines the Patch standard), from the client's perspective the API could be called like

PATCH /ticket/47321

[
    { "op": "replace", "path": "/author", "value": "David"},
    { "op": "replace", "path": "/statusId", "value": "1"}
]

More examples can be found here.

Community
  • 1
  • 1
Alexandru Marculescu
  • 5,569
  • 6
  • 34
  • 50