80

I'm building a inventory management system and I'm busy designing (thinking) of the API and my REST implementation.

I have the following resources and on the resource you can perform many actions/operations. Each operation will modify the resource and in some cases create a new resource and also create history or transactions.

I'm looking for some input from experts in regards to useability and acceptability in regards to URL and resource design. The gotchas and real world examples, any opinion or criticism welcome.

My concerns are that the whole application might be develop around this one big resource? My backend stack will be C# and servicestack framework and for frontend I'll be using HTML and AngularJS. Not that it makes a difference.

Scenario 1. Typical operation will be:

POST /inventory/{id}/move
POST /inventory/{id}/scrap
PUT  /inventory/{id}/takeon
POST /inventory/{id}/pick
PUT  /inventory/{id}/receive
POST /inventory/{id}/hold
POST /inventory/{id}/release
POST /inventory/{id}/transfer
POST /inventory/{id}/return
POST /inventory/{id}/adjustment


{
  "userID": "",       //who is doing the actions (all)
  "tolocationID": "", //new location for inventory (move/takeon/pick/receive/transfer/return)
  "qty": "",          //qty (pick/receive/takeon/transfer/return)
  "comment": "",      //optional for transaction (all)
  "serial": "",       //(takeon/receive)
  "batch": "",        //(takeon/receive)
  "expirydate": "",   //(takeon/receive)
  "itemCode": "",     //(takeon/receive)
  "documentID": "",   //(pick/receive/return/transfer)
  "reference" :"",    //(all)
  "UOM" :"",          //(all)
  "reference" :"",    //(all)
}

Is this acceptable in regards to standards. The other approach might be.

Scenario 2.

POST /inventory/{id}/move
POST /inventory/{id}/scrap
PUT  /inventory/{id}/takeon
POST /document/{id}/pick     //**document**
PUT  /document/{id}/receive  //**document**
POST /inventory/{id}/hold
POST /inventory/{id}/release
POST /document/{id}/transfer  //**document**
POST /document/{id}/return    //**document**
POST /inventory/{id}/adjustment

and then to change the resources.

Scenario 3. in my opinion wrong

POST /transaction/move/{...}
POST /transaction/scrap/{...}
PUT  /transaction/takeon/{...}
POST /transaction/pick/{...}  
PUT  /transaction/receive/{...} 
POST /transaction/hold/{...}
POST /transaction/release/{...}
POST /transaction/transfer/{...}  
POST /transaction/return/{...}
POST /transaction/adjustment/{...}

Any comments welcome, not looking for answer but more advice on design considerations?

Thanks for taking the time reading this entry!

Francois Taljaard
  • 1,339
  • 2
  • 12
  • 33
  • 8
    This sounds more like RPC than REST. What resources to URLs like `/inventory/{id}/move` identify? If that's an URL for a procedure call and not for a resource, than you are not doing REST. –  Aug 13 '14 at 14:05
  • 13
    I don't think "not doing REST" is a bad thing, as REST is naturally suited to CRUD operations, and this set of operations is clearly richer. I believe, in this case, there's nothing wrong with picking a RPC paradigm and not totally following REST. Depending on what aspects of the domain one needs the model, of course. – Victor Sergienko Aug 13 '14 at 19:30
  • 3
    @VictorSergienko I agree with the sentiment, but if he tags the question [rest], he's got to expect REST answers. – Eric Stein Aug 14 '14 at 02:25
  • 2
    @EricStein This is very helpful I think one of my big struggles is that RPC does not fit my requirements technology wise and thats why Im exploring alternatives. But at the same time out of respect I think for REST I'm trying to do it the right way,but the right way is again putting me in a position where it feels wrong,but not in a technology sense but business domain. I think I'm looking for someone to say: Hi you don't have to be to religious about it:-)Should I then walk away from REST and ServiceStack framework and climb back in bed with Microsoft webservice? – Francois Taljaard Aug 14 '14 at 05:44
  • Been doing allot of reading take a look at this article. https://zapier.com/engineering/when-rest-gets-messy/ – Francois Taljaard Aug 14 '14 at 05:44
  • 5
    @Francois, you don't have to change the technology stack. I believe Eric is talking about the ideological concerns, and so do I. You still can use HTTP+JSON in RPC style, or a webservice in a REST style. – Victor Sergienko Aug 14 '14 at 09:45
  • @VictorSergienko I think all of these comments are clarifying my original question. I think technologies like servicestack and ASP WEBAPI is enabling people to do things and then attach it to architectural styles like REST, but the way you implement the solution is what matters. In your opinion and experience do you see allot of business enterprise solutions using REST? – Francois Taljaard Aug 14 '14 at 10:48
  • Going off topic and subjective... I do. SOAP is older and hugely overloaded (http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/). All the three enterprise projects I participated in last years were using JSON in their webservices, and tried to abide by REST ideology. – Victor Sergienko Aug 14 '14 at 11:50
  • Out of curiosity, where did you end up going with this design? I'm wrestling with the same thing on an inventory like system where I need to support start, scrap, complete, etc operations within a manufacturing process. – Sam Storie Feb 05 '15 at 15:32
  • hallo @SamStorie, I went with a RPC style service using ServiceStack. Request - Response resources, I did use Get, Post verbs and trying to work my way to a Restful service. – Francois Taljaard Feb 09 '15 at 12:51
  • Thanks for the extra info. I think I'm going to try to turn these URL verbs into "pluralized" nouns and work towards using the HTTP verbs for the operations. So I will end up stuff like /objects/scraps, /objects/starts, etc where a GET lets me get a collection of those operations, POST lets me create a new scrap, start, etc, and so on. These URLs would then require additional data to have meaning, but this seemed to make sense to me (at this point anyway!). – Sam Storie Feb 09 '15 at 14:14
  • @SamStorie take a look at this, https://www.youtube.com/watch?v=QpAhXa12xvU at 19:29 and 39:00 min . Also a slide share http://www.slideshare.net/apigee/restful-api-design-second-edition (slide 48 and slide 74). – Francois Taljaard Feb 09 '15 at 16:46
  • @VictorSergienko, appreciate if you could share your experience about supporting RPC operations using REST – Maulik Modi May 14 '21 at 04:39

4 Answers4

122

Short answer:

Use actions at the end of the url to change state.

Github does it like this to star a gist: PUT /gists/:gist_id/star

Explained here https://developer.github.com/v3/gists/#star-a-gist

Long Answer:

Your objective is making your applications effortless to use an intuitive. Your users should use your app in the simplest possible way. Your users should not suffer the limitations or hard guidelines of the technologies you use.

So actions and operations are inherently not resources, but actions over resources. So they will not respond to a "resource to URI mapping" like REST is.

But you can use the best of REST, and still the best of URIs, combining both.

Remember:

The technology should work for you, and not you for the technology.

If you become an slave of technology, you will end up creating unusable applications or using ugly technologies like XML or Java Home and Remote interfaces, so you end up writing 5 files to create a hello world application.

BEWARE of the "shiny object syndrome". Google it.

Not because a technology is new or is "the new way of doing things", it means that is a good technology or you need to get distracted and let aside all other technologies to succumb to REST.

Take what you need from the technology and then make the technology work for you.

Using REST api does not mean you need to discard the capabilities of the URL and URI technologies.

References: https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful

zurcacielos
  • 1,495
  • 2
  • 9
  • 7
  • 22
    Best answer in my opinion. – LunicLynx Jun 27 '19 at 08:36
  • 1
    @LunicLynx thanks... we can't let a technology like REST override and discard the HTTP or URI technology. Fortunately GraphQL and other emerging technologies will help people to understand that REST is not a silver-bullet and has many, many cons, as good as some pros. Cheers. – zurcacielos Jul 03 '19 at 07:44
  • 2
    6 years later this is still a good question (I think) and after 6 years I still find value in the people responding. Thanks for the answer, using action at the end of URL is something small but I like it. – Francois Taljaard Oct 08 '20 at 07:43
  • 1
    @FrancoisTaljaard I'm glad you like it. My english was even worse 6 years ago . Still I managed to present the alternative idea to the mainstream. When we say "there is no right answer", it doesn't mean all answers are wrong. Some approaches are good in some space/time conditions. Like in a given company in a given market time, etc. We have no lasting friends, no lasting enemies, only lasting interests / Churchill – zurcacielos Nov 30 '20 at 04:13
  • 3
    Github's PUT /gists/:gist_id/star is not an action. The verb is here PUT, star is an object. Github put's a star (object) on the gist. PUT is reasonable, because it's idempotent request. POST /something/:id/move wouldn't be RESTful, since move is not an object. – goteguru Nov 24 '21 at 23:27
  • @goteguru I got your point. The mention of GitHub is an example, more or less inaccurate. But the whole message of my comment is that the partiture and pentagram gives you the basic idea. Now, that doesn't mean you need to demand your listeners (consumers) to learn music theory before listening to your music. Your interpretation of the music is or could be something distinctive of you. The world will not come to an end (not sure). That is my "message" without too much intention of holding a sacred truth. Thinking out of the "REST" box. I'm not trying and bend the spoon, that's impossible ⛔ – zurcacielos Nov 26 '21 at 02:25
  • @1P0 Ok, however a wrong example won't help to understand the point... We can see that this Github API is perfectly RESTful and faithfully following the principle. If you know a well established (REST) API which is using verbs at the end of the url, that would be a much better example. – goteguru Nov 26 '21 at 17:00
  • @goteguru your point is totally valid and an opportunity for somebody to research. In my case rather than the example you propose to find... I would weight the million of "very well stablished (REST) APIs" that have died, and entire products sent to trash I saw in the last 30 years. The most "correct" guy doesn't get the most beautiful girl (not always). If system A was pre-REST-era, REST evolved from A because it was different and didn't fully adhere to A. Difference and change may create a better system/way. The DNA have those mutations. Many fail. I'm for the Cognitive Flexibility. – zurcacielos Nov 27 '21 at 21:57
58

I have the following resources and on the resource you can perform many actions/operations. Each operation will modify the resource and in some cases create a new resource and also create history or transactions.

Fundamental to the REST architectural schema is the idea of using the HTTP verbs as the only verb, and not including verbs in your URLs. In your shoes, I would consider reworking your system to remove the verbs. It's hard to suggest a design without actually knowing what any of the verbs mean, but perhaps something closer to:

GET /inventory/{id}
PUT /inventory/{id} -- update with new location 
PUT /inventory/{id} -- update with new status (scrapped)

etc .. That's a more RESTful approach. Many of these actions look like they're really just PUTs that update multiple properties of the resource, such as location, quantity, comment field, etc. And perhaps scrap is DELETE? Hard to tell.

Another option would be to use POST, where the body includes the instructions for how to operate on the inventory item:

POST /inventory-transactions/{id}
{
    "action": "takeon",
    "newLocationId": 12345,
    ...
}

This gives you a lot of traceability, because every operation can now be tracked as a resource. The down side is a lot of complexity around the endpoint.

You can also break out some of the "verb" operations into resources:

POST /returned-inventory
{
    "inventoryId": 12345,
    "documentId": 67890,
    "comment": "Busted up",
    ...
}

This lets you easily look at inventory items by their status, which may or may not be helpful. You could, for instance, call GET /returned-inventory?documentId=67890 to get back all the returned items from the same document.

Hopefully there's some food for thought in there. It's really not going to be possible for anybody to tell you the "right" thing to do without knowing your business requirements in greater detail.

Eric Stein
  • 13,209
  • 3
  • 37
  • 52
  • can agree with this answer, Stein can you recommend any good websites thats more forum base or interesting reads on the topic. – Francois Taljaard Aug 14 '14 at 06:12
  • 21
    Nowadays it is preferred to use PATCH if you are just updating part of a resource (e.g. changing the location or status). PUT should be used to update the entire resource. – stannius Sep 14 '17 at 16:54
  • "Fundamental to the REST architectural schema is the idea of using the HTTP verbs as the only verb, and not including verbs in your URLs". This guy https://restfulapi.net/resource-naming/ and others contradict that. They recommend "controller", also called "action" verbs on resources. I think it's good advice. It just solve a ton of awkaward semantic/aesthetic edges cases with trying to contort everything into HTTP verbs on objects, and it's still consistent with rest. – spinkus May 29 '21 at 05:35
  • 1
    You are welcome to make up and do whatever you want. It's not REST, though. If restfulapi.net says otherwise, it's wrong. – Eric Stein Jun 01 '21 at 20:15
  • [REST doesn't say](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) that you have to use only HTTP verbs. It doesn't even say that you have to use HTTP. – szrg Feb 28 '22 at 11:35
  • The uniform interface of HTTP includes the HTTP verbs. Making up your own verbs means leaving the uniform interface. – Eric Stein Feb 28 '22 at 12:42
25

"Restful Objects", which defines a RESTful API, states that actions are valid.

Available actions can be discovered, enabled/disabled, and can give 'disabled reason' feedback.

Actions are 'invoked' using GET (query), PUT (idempotent), or POST(non idempotent)

Restful Object Spec (page C-125)

Patrick
  • 1,089
  • 14
  • 17
  • 1
    This is good thorough specification, even if you don't agree with it completely, it has a lot of good concepts like modeling domain services as objects that have actions – Jerico Sandhorn Feb 02 '16 at 12:37
1

My considerations about the following example:

POST /inventory/{id}/move
  1. The "move" term can be considered as a shortening for "move-request".
  2. In this case, the user is posting a request to move the inventory.
  3. When accepted, the request will trigger the corresponding server action.
  4. A request is some kind of resource, it can even be persisted by the server for history purposes or to trigger asynchronous tasks if not executed immediately.

Those are the main reasons why I consider that verbs can be used at the end of URIs without breaking any REST guidelines.

Another considerations:

  1. Make sure you're using this "request abstraction" only in cases where you don't have a a simple resource that can be posted or put.
  2. PUT inventory/{id}/manager is a better approach than POST inventory/{id}/set-manager, unless your request requires some params that are not properties of manager.
  3. In cases where your params doesn't fit an entity / valueobject properties, a POST inventory/{id}/manager-update would be recommended, which is, clearly, a resource.

Finally ... most of the REST guidelines examples covers only CRUD applications. Richer domains need more expressive abstractions than just use simple nouns from domain entities or value objects.

TPaim
  • 305
  • 3
  • 13