REST-ful URI Design _ 2PartsMagic Blog

download REST-ful URI Design _ 2PartsMagic Blog

of 17

Transcript of REST-ful URI Design _ 2PartsMagic Blog

  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    1/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 1

    REST-ful URI design

    This post is about URI naming. Designing URI names. Some tips and rules and conventions that you can follow when figuring

    out your applications URIs. The focus is on URIs for REST-ful applications. But many of the tips apply to any kind of

    website or application.

    REST-ful URIs and non-REST-ful URIs

    A REST-ful URI is a URI that identifies a domain resource (like a book or a shelf or a book loan in a library application) rather

    than an application resource (like a web page or a form in your application or website).

    Typically REST-ful URIs are for APIs. For programmers. But in many cases they will serve just as well for a regular

    website.

    non-REST-ful URIs are more likely to identify application resources like web pages rather than domain resources:

    /admin/updatebook.jsp?book=5

    /bookview.jsp?book=5

    /bookandreviews.jsp?book=5

    PS: There can be confusion about URIs and URLs (and URNs!). To get a URL just tack on a server (example.com) and a

    protocol (http or ftp) to a URI (/example): http://example.com/example. The URI identifies the resource. And a URL adds som

    information about how to get it.

    URIs do not matter with REST-ful applications

    This is what some people say. See the comments below. But is not true: URIs do matter. URI design matters. And URI

    design for REST-ful applications matters even more.

    The reason is that REST-ful apps are all about domain resources (like books and shelves and loans in a library application) rathe

    than application resources (like forms to reserve a book or pages displaying a book or who has loaned what).

    With REST-ful applications the first thing you need to do is to identify the resources you are representing in your system. And

    URI-design is all about how you can consistently name every one of those resources.

    What are the criteria for a good REST-ful URI?

    I assert a good REST-ful URI is:

    Short (as possible). This makes them easy to write down or spell or remember.

    Hackable up the tree. The user should be able to remove the leaf path and get an expected page back. e.g.

    2PartsMagic BlogBlogging web software development

    2PartsMagic REST-ful URI design About 2PartsMagic

    http://2partsmagic.com/http://blog.2partsmagic.com/restful-uri-design/http://blog.2partsmagic.com/about/http://blog.2partsmagic.com/http://blog.2partsmagic.com/about/http://blog.2partsmagic.com/restful-uri-design/http://2partsmagic.com/http://blog.2partsmagic.com/
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    2/17

  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    3/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 3

    Good URIs improve your site usability.

    Readable URIs increase your search engine traffic. People actually see and read URLs in Googles search results. And the

    are more likely to go to a page if the name of the page matches what they are looking for.

    How good URI design improves usability

    Users can find their way around more easily when there are good URIs. They have a chance of getting themselves unstuck

    inside the site structure. e.g. if they are at /conversations/conversation-10/todo-list-12 they can easily enough pop up to

    /conversations where all the current conversations are displayed.

    A good programmer looking at well designed URIs in a REST-ful API should be able to visualize your API merely by knowing

    some of the URLs.

    Non-REST-ful URLs

    I have always aimed to create decent urls. In non-REST-ful apps they would be good solid urls like:

    http://rimuhosting.com/ticket/startticket.jsp

    https://pingability.com/cp/register.jsp

    http://rimuhosting.com/order/startorder1.jsp?type=2&t-vps

    Typically when there is a different kind of page I create an JSP for that page. And the page name will reflect whatever is

    happening on that page.

    Non-REST-ful URIs are fine, they are just non-REST-ful.

    This post is nota debate about which is better out of REST-ful and non-REST-ful URIs. This post is about what makes a good

    REST-ful URI. If your URI is non-REST-ful it is simply non-REST-ful, and I make no claim that it is good or bad.

    REST-ful URIsThe RedRata team has recently started trying to create an application and we would like it to be a REST-ful application.

    REST-ful applications do not implement a specification (like SOAP, or XML-RPC, or ATOM). There is no validation service th

    will tell me if my REST-ful application is REST 1.0 compliant. There is no REST 1.0 BTW.

    Instead REST-ful applications are applications that follow REST-ful conventions.

    And there are conventions around what makes a REST-ful URI.

    Ive found that coming up with REST-ful URIs that I, and others, think follows proper REST-ful conventions is difficult.

    But the difficulty comes because of the importance of good URI design. Not so much that it follows some convention that a

    bunch of technologists have come up with. But because it improves end user usability.

    Examples of (possibly) REST-ful URIs

    In a quickly-recognizable-as-REST-ful app we would possibly have URLs like. e.g.

    http://rimuhosting.com/users/user-9/contact-details

    http://rimuhosting.com/planstype=vps to show VPS plans

    http://rimuhosting.com/plans/plan-miro2b to show the MIRO2B plan. Aside: this redrata.com WordPress blog runs on a

    RimuHosting Miro2 plan.

    http://rimuhosting.com/order/startorder1.jsp?type=2&t-vpshttps://pingability.com/cp/register.jsphttp://rimuhosting.com/ticket/startticket.jsphttp://www.useit.com/alertbox/990321.html
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    4/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 4

    http://rimuhosting.com/carts/cart-2/server-1 a server plan added to the cart, in preparation of checkout

    5 developers an infinite selection of URLs chaos ensues

    I came up with those sample URLs just now. If I were to come up with the same resources tomorrow would that list look the

    same? What if another developer in my team attempted the same task?

    Would the names be similar? Would we argue endlessly about which was the better way? Would there be any concrete guideline

    on which we could select one set over another? Would we even be aware of the URI design importance to worry? Would usabilissues and development chaos ensue?

    How to decide on which template or conventions do you use? How do you get everyone on the same page? How can you make

    so two developers independently adding a new resource to the app would use the same or similar URI?

    In order to try and get some consistency over how we design urls in RedRata REST-ful apps we have tried to come up with a

    convention for us to use. That convention and a discussion of the alternatives follows.

    Nouns, not verbs

    REST-ish URLs identify resources. Nouns. They tell you what they are.

    REST-ful URIs should not tell you what they do. No getPlan. Nor start-order.

    The do comes when you apply a verb an HTTP method to the URL. e.g. a HTTP PUT to a URI means update that resource.

    DELETE means to delete it. A POST typically means create something for me (e.g. a new order, or a shopping cart).

    Stateless URIs

    An example. On RimuHosting we have some long running operations. e.g. when we move a VPS from one host server across th

    globe to a different data center. So we create a move status URL and give it a status id. And then we use Ajax to keep pushing

    updates to that URL. Or the user can reload the page.

    There is a problem. That URL only works for that user on that session. They could not bookmark it, go home, and see it at home

    They cannot send it to a colleague and say Keep an eye on this move for me.

    Good URIs (REST-ful or otherwise) should be stateless. If I am looking at a document I should be able to share that URL with

    someone and they should be able to access the same resource.

    What they see may differ from what I see. e.g. since I may be logged in as an admin on a site and see a few more options than

    they do as a guest. But this is just a different representation of the same resource. Or they may even get a not authorized

    response if they are a guest, or a logged in user without the authority to see the resource.

    To get a stateless URI avoid reliance on session attributes. Transient things. If you need to store something, store it in a database

    (where database is probably some SQL database, but anything that is accessible by someone with a different session ID will do)

    Examples:

    Hey, have I got all the things you needed in my shopping cart? A URL of http://example.com/shoppingcart would not be

    something that the other person could easily see. If the URI was http://example.com/shoppingcarts/cart-12 then it could

    potentially be visible (e.g. if you had set a public flag on the cart, or if you and a colleague had a login each to a purchasing

    account on example.com).

    Example:

    Hey, what address do I need to set on my account? If the url is http://example.com/address then it likely represents the address

    of the currently logged in person. And what I will see (my address) is a different resource from what you will see (your address)

  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    5/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 5

    Same type of resource (address). Different instance: mine vs. yours.

    In this case consider a URI design of http://example.com/users/user-9/address.

    Then it is clear that we are talking about the address of a specific person. Whether you can see my address is a different matter.

    Stateless URLs can improve scalability

    A beneficial side effect of stateless URIs, where you avoid storing attributes associated with a session is that your application cascale across hardware more easily. As it will not matter, or matter as much if they shift from one web server to another since the

    URLs they see do no depend on some session state. e.g. worst case scenario they may just need to re-log in. To re-establish the

    identity.

    Personal URLs

    There is value having a URI like http://example.com/contact-details (meaning my contact details). Or preferably something tha

    indicates it belongs to the current user, like, http://example.com/users/user-me/contact-details.

    e.g. you may have a static page that wants to link to the users contact details. And at the time you show the page they may not b

    logged in.

    In that case http://example.com/users/user-me/contact-details could prompt for a login. Or if the user is logged in they the page

    could redirect to URL like, say, http://example.com/users/user-9-peter/contact-details

    The redirect in this case is important. Since the page on which the user ends up is their contact details resource. Whereas

    http://example.com/users/user-me/contact-details is a resource to findyour contact details location.

    Summary: if a resource is context sensitive (e.g. to a current user) create a separate resource finder URL. Make it clear that

    resource URI is context sensitive (e.g. including words like me or my in it). And have that resource redirect to the actual resourc

    when it is used.

    Further example: http://example.com/forecasts/cambridge/today redirects to, say, http://example.com/forecasts/cambridge/2009-

    04-26

    Extension or no extension

    If you use JSP then your files probably have a .jsp extension. And similarly for PHP and other apps. In an ideal world the

    technology you use on the back end should not force its way into the users face.

    Some sites have a .en URI for an English version of the content and a different URI with a .fr extension for a French localized

    version of the page. Would it not be better if a user could go to http://example.com/aboutus and get the page in their preferred

    language. And then share that URL with someone else who sees it in their own language?

    Some applications return different data if the user adds a different extension. e.g. they may ask for contacts.xml or contacts.json

    But different URIs imply different resources. Are the two data formats really two different resources? Or just two different

    representations of the same resource.

    With HTTP there are other ways you can negotiate content. e.g. via the Accept header.

    I assert that REST-ful URIs should identify a single resource. And different representations of that resource can be negotiated.

    e.g. via HTTP headers. I assert that things like language localizations, data formats, read only views, HTML forms, summary

    views, detail views, etc, are all just different representations of the same resource. I assert developers should work to keep all

    those representations on the same URI.

    I assert that we avoid extensions to indicate the representation of the resource.

  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    6/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 6

    Using Accept HTTP request headers to negotiate views.

    Having all representations of a resource on a single URI can be a tricky task for developers to pull off. It requires having a lot of

    control over receipt/dispatch of HTTP requests. And full and easy control of HTTP request and response headers. Not to mentio

    being able to serve up different human and machine languages and views for resources.

    Standard ways to negotiate the representation of a resource:

    Accept: text/html will return a full web page with site navigation and other linksAccept-Language to control the localization of the resource between different human languages.

    Accept: application/xml and application/json to get back data in these popular formats.

    Standard Accept headers break down with some view types

    But how do you negotiate other representations like a summary read only view of a resource /customer-9summary? Or a detail

    view /customer-9?detail=Y. Or a form to edit that person: /customer-9/edit

    These are introducing new URIs (suggesting these are therefore different resources). Yet I am asserting that these things are

    mere representations of the same resource, not different resources.

    But how else to solve the problem? These are all HTML pages (for argument sake). And weve only got the one text/html media

    type.

    Or have we?

    Using vendor specific Accept headers

    Instead, RedRata will be trialing a method to leave the URIs alone and just use a different Accept header for the odd/particular

    representations we need. We will be using vnd vendor specific, made-up media types.

    The RedRata vendor specific Accept types

    RedRata uses the {type}/vnd.{company}{type}+{subtype} convention.

    e.g. text/vnd.redrata.summary+html application/vnd.redrata.deep+json.

    We will be using those types to differentiate between, say a regular Accept: text/html (returning a page with the resource and all

    the site navigation) and say the following:

    Accept: text/vnd.redrata.summary+html returns, say, a HTML div element containing a read only summary of a resource.

    e.g. for a person maybe just their name. Or name and email. But not all their details: like address, phone, notes.

    Accept: text/vnd.redrata.detail+html the full detail for, say, a person. But it would exclude the fluff like site navigation,

    ads, and other things not directly related to the person resource.

    Accept: text/vnd.redrata.edit+html returns, say, a HTML div element containing a form element for editing the resource.

    With the form pre-populated with the resources current settings.

    Accept: application/vnd.redrata.deep+json for a deep copy of a resources JSON and all its sub-resources. i.e. grabbing

    everything in one HTTP request

    Accept: application/vnd.redrata.shallow+json for a shallow copy of a resources JSON (excluding any sub-resources). i.e.

    grabbing everything in one HTTP request

    Accept: application/vnd.redrata.shallow+xml and application/vnd.redrata.deep+xml work the same way, but for XML

    I am not aware of anyone else using this Accept approach with vnd (vendor-specific) media types.

    If you think the approach makes sense, please use it in your apps and help make our non-conventional approach more

  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    7/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 7

    conventional. Heck, we may even go so far as to register those media types.

    More available views of a resource => more usable API

    One of the goals RedRata has is that the applications we create with our REST-ful APIs will be easily embedded into our

    customers sites. e.g. with a quick Javascript/ajax call to yank a bit of information out of our app.

    By offering a variety of views (in HTML and JSON/XML) we have a better chance of being able to return something most

    suitable for our customers and users.

    Do cool URIs ever change?

    W3.org asserts that cool URIs do not change.

    I assert that seems a good guideline in most cases.

    Balance that against:

    Keeping things backwards compatible adds extra effort.

    Application resource structures change. And that should naturally cause URIs to change so they better reflect reality.

    We can improve our URIs over time.

    Good REST-ful applications should represent their state in their representations. For example by providing hyperlinks to

    other resources. A good REST-ful application should be fully navigable to anyone if they start at the / URI.

    If google can follow links on your site to get to the content, then the user will likely be able to find it again. 99% of the

    pages I need to get back to I get back to by searching for content on that page/resource. Particularly when I remember th

    domain it was on and I can slap a site:example.com into my google query.

    URIs dobreak. It is just a fact of life. People, and web services cope. No one or no service should expect to rely on

    unchanging URLs and get away with it for to long.

    To avoid URIs-that-change as much as possible consider keeping changeable/variable information out of the URI. e.g. Avoid

    using a users username in their home page URL if that username can change. Rather use something that will not change. e.g. a

    database id.

    More readable URIs using unique-id-plus-redundant-information (UPRI)

    How do you balance URIs-that-dont-change (implemented using unique, immutable database ids) with nice readable URIs (wher

    the readable bit for example a username or a conversation- or blog-post-subject is liable to change?

    Consider using the database id plus some other redundant info (like a username or name). The redundant information is not

    necessary to find the resource. If you have the unique, immutable id, like the database id, then you do not care about the other bi

    in the URI.

    e.g. /conversations/conversation-9-how-do-i-change-billing-details

    Canonical urls: coping with different URIs for the same resource

    With the unique-id-plus-redundant-information (UPRI) approach you could end up with different URIs for the same thing. And

    that is not ideal.

    In the case of different URIs pointing to the same resource (e.g. when you are using unique, immutable ids plus redundant bits

    you should consider indicating in your response the canonical or preferred link for that resource.

    You can do this inside HTMLs HEADs REL tag. Or in HTTP response headers. Using Location, Content-Location or Link

    http://www.w3.org/Provider/Style/URIhttp://www.ietf.org/rfc/rfc4288.txt?number=4288
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    8/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 8

    e.g. see Googles post on specifying canonical URLs or Mark Nottinghams Link header proposal. See also Ben Ramseys cool

    URIs dont change post.

    Redirects/Locations work, but who wants the HTTP latency overhead? Plus if you use a pretty URI that then goes straight to a

    different location (and changes the browser address bar) then no one will get to appreciate your pretty, readable URI. And they

    will likely feel less inclined to love it and bookmark it and tell their friends on social network websites about it.

    Browser urls are user interface (UI)

    URLs that appear in the browser address bar are part of the UI (user interaction). They MUST be hackable.

    So any path used in a browser youd expect to produce a decent HTML page all the way up the tree. e.g. youd want there to b

    no 404s. Nor any access denieds.

    The digging-deeper-path-and-backspace convention

    General rule: if you are on a page and you are clicking into an item on that page, drilling down into more detail on that item,

    then the we would generally just add the extra path segment to the original URI. e.g. from conversation page to todo list item

    would be /conversations/conversation-1 becomes /conversations/conversation-1/todo-list-5. Thus you can go back to where you

    were by removing the end path segment.

    General rule (rephrased): If you are clicking down a resource heirarchy (e.g from conversations to conversation to conversation

    item to ) the back key SHOULD be the same in most cases as removing the URLs last path segment.

    Similarly if you are on /conversations/conversation-1 and you click on the all todo lists in this conversation link you could end

    up on /conversations/conversation-1/todo-lists. From there you click on a particular todo list. In this case you get to

    /conversations/conversation-1/todo-lists/todo-list-5 . You can remove the last and end back up on the page you had come from,

    satisfying the digging-deeper-path-and-backspace rule. But note that /conversations/conversation-1/todo-lists/todo-list-5 and

    /conversations/conversation-1/todo-list-5 will point to the same resource. So you would want to use the HTML or response

    headers to indicate the canonical url.

    Putting our URI design thoughts into practice

    The first step in URI design is to identify your resources. In the examples here we will be talking about a hypothetical applicatio

    that manages conversations. OK, its not hypothetical. It is an actual application we are building. And this is the actual

    document where we try to figure out what our URIs are going to look like.

    The main resources/things in our application are conversations. Each conversation can have one or more conversation items like

    message going back or forth or a todo list or a status update. And some of the conversation items can have collections of other

    resources. e.g. a todo list can have a number of associated todo items.

    Choosing a URI schemes for resource hierarchiesLet us look at what URIs we could use to represent our conversation-related resources.

    plural-root-plus-singular-root: e.g. /conversations and /conversation/{id}

    /conversations : all conversations

    /conversation/{id} : a specific conversation (note singular not plural)

    Cons: You cant hack the url. If you remove the id you get /conversation and not the list of conversations you were

    expecting/hoping for (which is at /conversations)

    http://benramsey.com/tag/cool-uris-dont-change/http://tools.ietf.org/html/draft-nottingham-http-link-header-04http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=139394
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    9/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 9

    plural-singular-id: e.g. /conversations/conversation/{id}

    /conversations : all conversations

    /conversations/conversation/{id} : a specific conversation

    Issue: what is the page at /conversations/conversation going to show? Do you want a page there? If you do not have a page th

    made sense to show there then that URI is not really hackable.

    Issue: it is kinda long

    plural-id: e.g. /conversations/{id}

    /conversations : all conversations

    /conversations/{id} : a specific conversation

    Pro: vs. option plural-root-plus-singular-root you can remove bits from the path and work up the ownership heirarchy

    Cons: If you wanted to use a url like /conversations/new then youd need to be able to dissambiguate a conversation like

    /conversations/5431. e.g. if all your conversation ids are numbers then this could work well. Else youd need to avoid naming

    collisions in case you ever had a conversation id of new. If this could be the case you may be better off using the plural-name-

    and-id template.

    Option plural-id-id-id /conversations/{id}/{id}/{id}

    What about when you have deeply nested resources?

    /conversations : all conversations

    /conversations/{id} : a specific conversation

    /conversations/{id}/{id} : a specific conversation item

    /conversations/{id}/{id}/{id} : e.g. a todo item on a todo list on a particular conversation

    Disadvantage: with deeply nested hierarchies you lose meaning about what each path is

    plural-name-id-name-id-name-id: e.g. /conversations/conversation/{id}/todo-lists/{id}/todos/{id}

    /conversations/conversation/{id}/todo-lists/{id}/todos/{id} : e.g. a todo item on a todo list on a particular conversation

    Advantage: you know what each id means.

    Disadvantage: If you expose /conversations/conversation/{id}/todo-lists/{id}/todos/{id} in a browser url bar, then youd need to

    support having a UI for having each part of that directory tree. e.g. /conversations/conversation/{id}/todo-lists/{id}/todos you

    may want to do that, if so fine. Else if you dont want to provide a UI for that there would be an issue. e.g. user gets error page

    Meaning the URI is not so hackable.

    Option plural-name-and-id /conversations/conversation-{id}

    /conversations : all conversations

    /conversations/conversation-{id} : a specific conversation

    Pros: similar to plural-id.

    plural-name-and-id-name-and-id-name-and-id: e.g. /conversations/conversation-{id}/todo-list-{id}/todo-

  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    10/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 10

    {id}

    We extend the plural-name-and-id for nested and deeply nested resources.

    /conversations : all conversations

    /conversations/conversation-{id} : a specific conversation

    /conversations/conversation-{id}/todo-list-{id}/todo-{id} : e.g. a todo item on a todo list on a particular conversation

    Advantages: hacking the url by removing a path will give you the todolist, the whole conversation, or a set of conversations

    At RedRata we are opting to use this plural-name-and-id template for nested resources.

    /conversations/conversation-{id}/todo-list-{id}/todo-{id} : e.g. a todo item on a todo list on a particular conversation. And if you

    remove the last path you get /conversations/conversation-{id}/todo-list-{id}, the todo list and all its items. And if you remove th

    last path from that you get /conversations/conversation-{id} the conversation.

    In this example, there is no user interface to the URL to get an individual conversation item. Why not? Well what if we dont

    want to provide that page? The resource exists. We just dont want a user to go there and get a hey, no content we want to show

    you for this page message

    Of course we may change our minds later on and want to have a page available that shows just a single conversation item. i.e. a

    single message in a conversation. In that case we can expose a url like (just a slash has been added):

    /conversations/conversation-{id}/todo-list-{id}/todo-{id}

    name-plus-id-plus-redundant: e.g. /conversations/conversation-9-where-is-apache-installed

    We can convert the unique, but opaque, /conversation/conversation-{id} to the just as permanent but more readable

    /conversation/conversation-{id}-{subject}

    We do the database lookup based on the id. We ignore the subject (as that could change over time).

    On our response we indicate the canonical resource e.g. /conversation/conversation-{id}.

    Pros: user friendly, permanent URI

    Cons: a bit long, a bit of extra work to respond with the canonical resource location.

    Sample URLs for the RedRata commapp

    Hackable urls:

    /conversations/conversation-{id}/todo-list-{id}/todo-{id}

    /conversations/conversation-{id}/message-{id}

    /conversations/conversation-{id}/email-{id}

    /conversations/conversation-{id}/messages

    /conversations/conversation-{id}/messages/message-{id}/conversations/conversation-{id}/message-new for creating new messages. After the message is created it will have an id. And

    the url will be the same except the new becomes the id. Nice and neat.

    Creating resources

    Creating new resourcess (when that resources parent does not exist yet) presents a particular challenge with REST-ful

    applications.

    The REST-ful policing squads will knock on your door if you overtly offer verbs in your urls. Like /conversations/create-new-

    conversation. That is seen as exposing a process not a resource. You could always have your defense lawyer argue the process i

  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    11/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 11

    the resource, I suppose.

    You couldsend a HTTP POST to a URI like /conversations to create a resource with. But that could be ambiguous. What would

    that create? A conversation? What if other things lived under conversations? Like staff? Or audit logs? Or billable hours?

    Here are some examples of URIs we could use instead:

    /conversations/conversatation-{id}/message-new existing conversation create message

    /conversations/message-new create a new message and while we are at it it would also create a new conversation in which to

    put it.

    These URIs would return information (e.g. an HTML form, or a prototype JSON/XML representation on a HTTP GET). And

    would create the new resource on a HTTP POST.

    Here are some URIs we would likely notuse:

    /conversations/conversatation-new/message-new implies /conversations/conversatation-new creates a new converstation. But

    that isnt something we want to allow them to do. i.e. this URI is hackable in a way we do not want it to be

    /conversations/conversatation/message-new implies the same as /conversations/message-new but if we had nothing to show at

    /conversations/conversatation then this url would be hackable in a bad way.

    Direct URLs vs. hackable URLs

    With most deeply nested resources if you have the resources ID you can probably figure out the objects that own it up the tree

    In this case you can have short/simple/direct urls like:

    /conversation-{id}

    /message-{id}

    e.g. same resource:

    /conversations/conversation-{id}/messages/message-{id} (which implies there is a meaningful page at

    /conversations/conversation-{id}/messages, say one that listed all messages cf. todo lists, for a conversation)

    /conversations/conversation-{id}/message-{id}

    /message-{id}

    These direct URLs may be easy/quick/handy for programmers. e.g. the makers of the REST-ful service, or developers using theREST-ful service as a client.

    They are not easily hackable by end users. e.g. you cannot go from that direct url to the containing resource. So do not use them

    in where you would need a hackable/discoverable/end-user-editable url.

    As usual when there is a choice of URIs for a single resource select your canonical URI and report it in your response.

    Some RedRata conventions

    The main url is /conversations/conversation-{id}

    There MAY be a link on individual conversation items. e.g. that goes to /conversations/conversation-{id}/message-{id}

    IF you have a page that shows a list of message type items in a conversation have /conversations/conversation-{id}/messages

    IF you click from that page to an individual page then that pages url SHOULD be /conversations/conversation-

    {id}/messages/message-{id}

    Apparently the theme I am using does not have user comments on pages, just posts, so if you have any thoughts on this page

    youll need to make any comments over on this blog post.

    http://addthis.com/bookmark.php?v=300http://redrata.com/2009/04/rest-ful-uri-design-verbs-vs-resource-nouns/
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    12/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 12

    26 Comments

    Greg

    Posted May 30, 2012 at 10:02 | Permalink

    This is a very interesting and vey good article !

    I am wondering though how we can keep that nice URI design for a tree structure.

    Lets say I want to manage some tasks lists. Each list can contain tasks and / or other lists (nodes and leaves in fact).

    I am thinking about 3 designs :

    1) /lists/{id_list1}/lists/{id_list2}/lists/{id_list3}/tasks/{id_task1}

    I am afraid that such a design could lead to really long URIs if the tree has a lot of levels.

    2) /lists/{id_list1}/{id_list_or_task1}/{id_list_or_task2}/{id_list_or_task3}

    This one is shorter but less readable.

    3) /lists/{id_list_parent}/{id_list_or_task_child}

    This one is short and can describe thousands levels trees, but I feel like somethings missing

    What would be your advice between these 3, or is it another smarter way ?

    Danilo Recchia

    Posted June 13, 2012 at 15:03 | Permalink

    Great post!

    j0kPosted June 18, 2012 at 05:49 | Permalink

    In addition to this article, here is a really good presentation by David Zuelke about how designing http interface and restful webservice.

    Pete

    Posted June 18, 2012 at 08:14 | Permalink

    Im going to pull a well actually here, I apologize in advance. Strictly speaking, a particular URI/URL design has little to do with REST-ful vs. Non-REST-ful. A

    system can perfectly adhere to the ReST constraints with URLs like /my/moppets/a/b/cdef as long as things like statelessness, Hypermedia As The Engines Of

    Application State (HATEOAS), etc as observed.

    A good URL design certainly helps with SEO, human user URL changes like finding the parent collection for a particular item, but lets not conflate that with ReST.

    John

    Posted June 18, 2012 at 10:14 | Permalink

    Theres no such thing as RESTful URIs. You may want to go back and read Roys thesis before you through around terms like that.

    Michele

    Posted June 18, 2012 at 11:08 | Permalink

    I came across this article through twitter, had no I idea was bound to rimuhosting, of which I have been happy customer for years

    Said this I must say I do not understand all this adversion for old opaque query string.

    I think also that paths are hierarchical by nature while context might be not.

    http://www.tenslashsix.com/http://www.slideshare.net/Wombert/designing-http-interfaces-and-restful-web-services-sfliveparis2012-20120608http://blog.wildtrip.net/
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    13/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 13

    For example take an Employee that books a Room for a meeting, in the booking URL we need both a ref to the Employee and the Room, what would be the correct

    path for this URL following your guidelines ? Would you force order on the segments ? You write about nested resources and level of nesting, but what is nested in

    what, in this case ?

    I think that all URL are restful and for me rest is more about sending links to change state to the clients (as usually happens in html apps but not in soap) than building

    URI in some way or in an other.

    Of course I might be wrong

    Peter BryantPosted June 18, 2012 at 11:55 | Permalink

    A restful URI identifies a resource (cf. a page, or a function or a form).

    So in the case of an employee booking a meeting room the resource is the meeting (the resource is not the room or the employee).

    So create a meeting with a POST to /meetings/new (with form data to identify employee, room id and time). Then view the resource at /meetings/meeting-982-john-

    room5

    Michele

    Posted June 18, 2012 at 13:11 | Permalink

    Hi Peter,

    thanks for th e answer.

    So if I get it well, query string is ok in this case.

    My extremist old way idea was:

    insertBooking.do?room=3&employee=2

    yours,if I am correct, is

    /bookings/new?room=3&employee=2

    There is one piece of information more in your 2 segments path version that in mine is lost in the page name. Of course is much nicer your version and that piece of

    information more can be used to hack the uri.

    Sorry if I am long and taking the occasion of this nice article to make questions about rest-philosophy, but what I am trying to discover is this: are URI(s) written in one

    or the other way really relevant for following rest architecture or are they just a plus ?

    I am tempted to think they are just a plus, what i see essential instead is that the uri-represented *resource* must be a _rest-resource_, so it must expose to clients URI

    representing other resources allowing client to perform state transition, then if the URIs are written in one URI syntax or the other it does not matter so much.

    What you think about it, I am getting it right ?

    Thanks

    Michele Vivoda

    David Zuelke

    Posted June 19, 2012 at 03:00 | Permalink

    In REST, it does not matter what your URLs look like, because all interactions are driven through links and their relations.

    Or, in other words: you ve likely missed the HATEOAS/Hypermedia aspect of REST, which is the most important p art of the Uniform Interface constraint:

    Also see Fieldings musings on the matter, e.g. http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

    David Zuelke

    Posted June 19, 2012 at 03:02 | Permalink

    Also, a page or a function or a form are not resources, but merely *representations* of resources. Resources and their representations are conceptually separate. Hence

    *Representational State Transfer*.

    Recommended reading: REST in Practice, a really great book that step by step teaches what REST is about (Hypermedia and HATEOAS, not URIs or status codes or

    http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    14/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 14

    headers) and shows the benefits of infrastructure that doesnt even rely on a specific structure for its URLs (REST is about distributed network applications, not about

    HTTP or whatever else).

    Peter Bryant

    Posted June 19, 2012 at 10:58 | Permalink

    +David Zuelke I agree: A REST-ful URI identifies a resource (rather than a page, or a function or a form).

    This is an article about URI design. Particularly URIs that may be used in a REST-ful API. When you build REST-ful applicaitions you can often do a better job of it if

    you think carefully about the design of your URIs.

    Michele

    Posted June 19, 2012 at 12:11 | Permalink

    >In REST, it does not matter what your URLs look like, because all interactions are driven through links and their relations.

    This is what I thought,is a plus. I will give a try to the book, thanks.

    I read some time ago the article from Fielding, but I like to read it again from time to time, still not got it fully -).

    Am I getting right that is essential that a representation of a resource in a rest architecture should provide -links- to the possible actions on the resource or related

    resources (application state changes)?

    Michele

    Vicente Gallur Valero

    Posted June 20, 2012 at 22:12 | Permalink

    Great article, very interesting and well explained. The only subject I dont agree is dropping the language from the URI for resources in different languages.

    I consider a translation a different resource and not a representation of the same thing in other format, as usually the translation is partial, localized, not exact, or simply

    doesnt exist.

    Also for practical reasons I find more useful you can link the resource in a concrete language, as it gives more control on what you want to link, and the user client may

    not share any of its Accept-Languages with the resources languages. You can then provide a default language, but could be a different one the original linker wanted

    to share and ending with ununderstandable content.

    For PUT, POST and DELETE, altought you can specify the language on the body of the request I think it should go on the URI, as you are modifying just that language,

    I see it as a different resource.

    Darrel Miller

    Posted June 27, 2012 at 17:16 | Permalink

    and just one more time There is no such thing as a RESTful URL.

    And I have found that designing by URI does not produce great results. It is much better to identify resources and the relationships between those resources. Once you

    have done that, picking URIs to identify those resources is usually pretty trivial.

    Sukant Hajra

    Posted September 6, 2012 at 12:57 |Permalink

    I believe theres some good advice in this post, but theres also unnecessary misinformation in the beginning about the difference between URIs, URLs, and URNs. I

    understand that this has been a source of confusion for some time, but I think the dust is settling. Although we may still debate what these terms mean, I think we can be

    more sure about what these terms do not mean.

    Heres the problem. URIs are notthe tail part of a URL. URLs are a type of URI, as are URNs. URLs are designed more for resolving.

    The Wikipedia page about thisis not too bad. But in case youre looking for a more official opinion, the W3 issued a nice retrospective report to help clarify the matter.

    It doesnt resolve all confusion, but it does a good job acknowledging how semantics have morphed as the internet has morphed.

    Daniel Halperin

    http://www.halper.in/http://www.w3.org/TR/uri-clarification/http://en.wikipedia.org/wiki/Uniform_resource_identifier#Relationship_to_URL_and_URNhttp://www.vgcomunicacion.com/
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    15/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 15

    Posted December 7, 2012 at 13:52 |Permalink

    Hi Peter,

    Helpful article. I wonder if you have any intuition on how the parser code for these URIs works. For instance, in JAX-RS you annotate each class and function with the

    path that should call it. So the class representing a Conversation resource might be annotated with @Path("/conversations"). The function that handles an

    individual conversation would be annotated with @Path("conversation-{conversationId}").

    If there is an alternate URI to, e.g., /messages/message-1/conversations/conversation-1how would the annotation structures work? It would seem complicated

    and error-prone to predict all possible combinations of URIs to put the same functions in every resource.

    How do you design your parsers?

    Peter Bryant

    Posted December 7, 2012 at 14:03 |Permalink

    It is probably best to avoid different paths where possible. And just use a single URI for each resource.

    e.g. Id argue a conversation includes a message but not vice versa.

    As far as the parsing go es I have a class per resource. For @Path annot ations I return an instance of the appropriate jaxrs class. The JAXRS class represents the resource. it

    doesnt have to care about the path the user took to reach it.

    Make sense?

    Daniel Halperin

    Posted December 8, 2012 at 08:04 |Permalink

    Peter,

    Thanks for the reply.

    In your examples, you often have multiple ways to get to the same resource. Are you now saying that we shouldnt do that?

    In any case, with a Google search inspired by your message, I found the Subresources technique described here, which seems to answer my question.

    Thanks so much!

    Dan

    JV

    Posted December 17, 2012 at 05:11 |Permalink

    Hi,

    Great article.

    I whant to ask your opinion about URI Design.

    I need to develop a REST API and I have doubts about the URI design.

    Scenario:

    1 Im developing one REST interface to a set of services.

    2 each service is divided from the logical point of view in several parts ( not resources).

    3 each resource can be accessed in two ways A and B

    What is the most appropriate URI design?

    /service1/part1/resource?{A|B}

    /service1,part1,resource?{A|B}

    espinete

    Posted March 12, 2013 at 01:37 | Permalink

    For separating parameters, are semicolons bet ter than ampersands?

    https://cwiki.apache.org/WINK/jax-rs-resources-http-methods-and-paths.html#JAX-RSResources%252CHTTPMethods%252CandPaths-SubresourceLocatorhttp://www.halper.in/
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    16/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    http://blog.2partsmagic.com/restful-uri-design/ 16

    Frogblatterbeast

    Posted April 23, 2013 at 20:28 |Permalink

    While I understand that REST isnt specific about URI design, I completely agree that good , semantic URI design is important for a good web application, just as

    everyone takes it for granted that functions, classes and compilation units in traditional software engineering are given readable and descriptive names. It really doesnt

    matter that much whether the URI is consumed by a human or a machine. If you spend some time thinking about your URI design, you will most certainly end up with a

    better and more business-driven application design.

    Doug Moscrop

    Posted June 16, 2013 at 03:12 | Permalink

    This is an article about URI design. Particularly URIs that may be used in a REST-ful API. When you build REST-ful applicaitions you can often do a

    better job of it if you think carefully about the design of your URIs.

    URI design is an oxymoron servers need to control their namespaces, and hierarchy has no meaning. I dont disagree with readable URIs, but thats purely for

    human beings to muck about. From an API perspective, from a functional perspective, every resource could be mounted via some GUID and youre still as REST (or not)

    as you are with well-designed URI syntax.

    You should have written an article on relationship design because thats a key part of hypermedia -based state transition.

    e.g. Id argue a conversation includes a message but not vice versa.

    This is incredibly far off the point. Youre trying to think about your domain and your domain does not present itself directly through your API what matters is state

    transition. From a representationof a given resource, what are my possible state transitions? You need to express those as hyperlinks. A conversation could be acollection-like resource of hyperlinks to individual messages. Those messages have hyperlinks too. What links? Well, thats the important part of the design. The part

    you seem to have glossed over.

    JohnPaul

    Posted July 16, 2013 at 17:50 |Permalink

    Nice information about URI naming

    Caleb Cushing

    Posted March 17, 2014 at 08:01 | Permalink

    Im curious how Using vendor specific Accept headers has worked out? Im looking at that for a solution to thishttp://programmers.stackexchange.com/q/232556/2331

    Caleb Cushing

    Posted March 17, 2014 at 09:14 | Permalink

    answers to this question about whether http clients check the mime type when determining to use a cached response seems relevant, if they dont then using the same uri

    with differnent mime types wouldnt really work safely, as the cache should give you the same response regardless of a new mime type

    http://stackoverflow.com/q/22441874/206466

    Dave Schinkel

    Posted April 9, 2014 at 07:50 |Permalink

    @David Zuelke

    Wrong, and this is the kind of half bake cowboy driven thinking that drives me crazy with some people (no offense David but I just had to say this).

    This is like analogy to say we do TDD but we feel we can skip the blue step in TDD at times.

    The URI matters as it ties to a RESOURCE, so its all tied into REST and in how you overall design your RESTful API. The URI tells the server what resource its

    looking for and the convention MATTERSyou may do it slightly different but for the most part theres a pretty consistent pattern people follow with RESTful URIs.

    What if youre coding for example ASP.NET MVC. You would want your URLs to still request resources and your route table to bind those to specific controllers for

    processing. How can you do that if you dont have a pattern that promotes REST in your URL? meaning youre representing resources! (instead of RPC style).

    Sure hypermedia is critical in the response but you dont take out the URI part saying its not critical or somehow doesnt relate or matter to REST.

    http://code-zest.blogspot.com/http://stackoverflow.com/q/22441874/206466http://xenoterracide.com/http://programmers.stackexchange.com/q/232556/2331http://xenoterracide.com/http://www.fieldservicemanagement.org/
  • 8/12/2019 REST-ful URI Design _ 2PartsMagic Blog

    17/17

    5/23/2014 REST-ful URI design | 2PartsMagic Blog

    The 2PartsMagic writers work on the coal face of web-based-, software-as-a-service-, Java-focused developers. They work on sites like:

    InboxHarmony, the collaborative email client for support teams

    RimuHosting dedicated servers

    RimuHosting VPS servers

    Zonomi DNS hosting

    Pingability website monitoring and alert service

    Bakop, FTP-based o ffsite server b ackups

    Blogging on customer service

    2 Trackbacks

    By REST-ful URI Design: verbs vs. resource nounson April 25, 2009 at 18:22

    By Bra artikel o m RESTful URI:s Stacktrace.seon April 19, 2010 at 22:27

    Post a Comment

    Your email is neverpublished nor shared. Required fields are marked *

    Name*

    Email*

    Website

    Comment

    You may use these HTML tags and attributes

    Post Commen

    Security Question:

    What is 2 + 4 ?

    IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)

    http://stacktrace.se/2010/04/19/bra-artikel-om-restful-uris/http://redrata.com/2009/04/rest-ful-uri-design-verbs-vs-resource-nouns/