1

When I design a restful API with the asp.net web API do I have to keep in mind that my client side deals with url design representing a state machine?

To make it more clear I am also talking about containment relationship in URL`s.

For example:

I have a User entity which can have many Schooylear entities. I have a Schooylear entity which can have many Period entities.

This results in three web API controller. UserController, SchoolyearController, PeriodController. Now I ask my self should I expose routes like:

api/users/1/schoolyears/2013-2014/periods/2014-01-01

The question would be now how should I map the http route ???

I have actually never seen routes like the above one rather routes like:

api/users/1
api/schoolyears/2013-2014
api/periods/2014-01-01

BUT the above route with the containing relationship would be really helpfull for the user if visible in the url bar...

OR should a restful API not offer a url design representing a state machine ? You see I am confused where the responsibility of the client starts or for the server ends...

Elisabeth
  • 20,496
  • 52
  • 200
  • 321

2 Answers2

1

A RESTful system does not care what your URIs look like. Web frameworks care about your URI structure. Wanting to use your URI as piece of "UI" is a valid concern.
Having longer URIs with multiple path parameters was not the easiest thing to do in Web API v1. With Attribute Routing it should be easier.

The only thing you need to be cautious about is generating hierarchies where the same conceptual resource appears in multiple places in the hierarchy. That's not a good idea for caching.

You don't want to be in the situation where you have,

api/users/1/schoolyears/2013-2014/periods/2014-01-01

And

api/users/1/periods/2014-01-01
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • "You don't want to be in the situation where you have,..." YES I want to be in that situtation! When I understood msfanboy correctly I need mysite.com/#/users/1/schoolyears/2013-2014/periods/2014-01-01 this will have no effect on the server routes because the hashbang is client side routing. And again I NEED such an url how else will the user be able to bookmark a link and load it quickly again? The link needs the whole chain of information else its not possible to load the period for the year 2014 1th january. – Elisabeth Jan 14 '14 at 18:50
  • @Elisa My assumption (and maybe it was incorrect) was that both of those URL would return the exact same representation. If so, you do not want to have two URIs that return the same representation. You can have one URI return a redirect to the other. That will allow both URIs and won't break caching. – Darrel Miller Jan 14 '14 at 18:52
  • @Elisa I haven't yet figured out what the relevance of the URI fragment is to your question. – Darrel Miller Jan 14 '14 at 18:54
  • heck why does the "@Darrel" not work? Anyway... We both was wrong. You first... your assumption was wrong that I would use both URL. Me last... I have not really seen the "And" concatenation... From What I know now is that I do not have to touch the server routes but the client side UI routing. I also think due to my confusion the question title is misleading and I will rephrase it just now. – Elisabeth Jan 14 '14 at 21:55
  • @Elisa The "at" Darrel will not work because it is a comment on my answer so I will be notified anyway. – Darrel Miller Jan 14 '14 at 23:06
0

When you optimize for a stateful javascript client using a framework like angularjs then your composed/nested views will dictate the construction of your url`s. You do not have to do anything special on the server. Just keep your routing:

api/users/1
api/schoolyears/2013-2014
api/periods/2014-01-01

as you want it. These routes have nothing to do with the client state these routes forward the client request not more.

On client side you set up the routes with placeholders which are customerId`s

or

orderId`s. When you change now a customer in a combobox you can update your route with the new selected customerId and navigate to it to ge the according orders.

what you do on client side is just changing the url without redirect:

jquery: change the URL address without redirecting?

You just create a "url" after the hash like #/customers/1/orders/2

If you do not like the hashbang you can also go for html5 push state:

http://badassjs.com/post/840846392/location-hash-is-dead-long-live-html5-pushstate

Community
  • 1
  • 1
msfanboy
  • 5,273
  • 13
  • 69
  • 120