skip to Main Content

Current situation

I am developing an Online Order Management system application with PHP and I need to design REST resource mappings through URL scheme.

I have typical resources:

  • Customer (has Orders)
  • Order (has Tickets)
  • Ticket (has Messages)
  • Message

I am thinking of something like this:

  1. Customer profile:

    example.com/customers/{customer-ID}
    
  2. Orders for {customer-ID}:

    example.com/customers/{customer-ID}/orders
    
  3. Tickets for {order-ID}:

    example.com/customers/{customer-ID}/orders/{order-ID}/tickets
    
  4. Messages for {ticket-ID}

    example.com/customers/{customer-ID}/orders/{order-ID}/tickets/{ticket-ID}/messages
    

Findings

One day of googling and I found these qutoes:

  1. Namespacing features behind the username like

    example.com/{username}/followers
    

    are great solutions for public features that belong to each user individually.

  2. Private things, such as account settings, should never be namespaced behind the username, and should just appear after /account or /settings.

  3. It’s best to keep the base resource URLs as lean as possible. Filters, sorting requirements, advanced searching and pagination can all be implemented as query parameters.

  4. A query string should be treated as an optional addition to the page; the URL should work to produce a valid and useful page even when it’s removed.

  5. In a good, hackable URL, a human can adjust or remove parts of the path and get expected results from your site. They give your visitors better orientation around your pages, and enable them to easily move up levels.

  6. By embedding a unique ID early on in your path, you can have long, fully descriptive URLs when needed but still enjoy the reliability of shorter URLs and the speed of ID lookups.

  7. Adding multiple keywords to URLs may help with SEO, but it will confuse your users. Also, you’ll quickly run the risk of being marked as a keyword spammer.

Questions

  • Am I doing things wrong?
  • Shall I avoid namespacing customers, orders, tickets and messages?
  • Does it have any real major security concern?

Thanks in advance!

2

Answers


  1. If all the relationships you describe are one to many (not many-to-many) than I don’t really see what you gain by having URL’s that, for example, contain a customer id, when the order id is known. It is redundant information, and will provide no additional useful information in your controllers.

    In fact it may cause MORE complexity than desired, as now you have to deal with cases where the might be a customer to order id mismatch. You now have to check all those conditions and return a bad request response if those bad conditions occur. Why add that overhead?

    Perhaps just:

    Customer profile:

    example.com/customers/{customer-ID}
    

    Orders for {customer-ID}:

    example.com/customers/{customer-ID}/orders
    

    Tickets for {order-ID}:

    example.com/orders/{order-ID}/tickets
    

    Messages for {ticket-ID}

    example.com/tickets/{ticket-ID}/messages
    

    If however you had a many-to-many relationship, this might change. Say for example that a customer could enter a single ticket that covers multiple orders (which means the tickets are now more related to the customer than to the order itself), then you might need URL’s like the following in addition to those shown above:

    See all orders for a given ticket:

    example.com/tickets/{ticket-ID}/orders
    

    See all tickets for a customer:

    example.com/customer/{customer-ID}/tickets
    
    Login or Signup to reply.
  2. Am I doing things wrong?

    It depends. You seem to be on the right track but you would better decide what functionality your service should provide first. Otherwise you might end up with an infinite number of url(resources) to implement. For example, if you need to expose a list of orders across all client you will want to have example.com/orders resource with query string parameters to specify search criteria. Otherwise, one will have to query all clients first and then in a loop send requests to example.com/customers/{customer-ID}/orders to get all orders across all client.
    So first think what functionality your service need to expose and then design the resources for it.

    Does it have any real major security concern?

    It has nothing to do with url(resources) design. Authentication and authorization info usually goes in the http headers.

    Also please consider adding versioning info to your urls. It turns out to be super helpful when you have to support several versions of your services

    example.com/v1/customers/{customer-ID}/orders
    

    or

    v1.example.com/customers/{customer-ID}/orders
    

    etc.

    Lastly, if you are going to support multiple representation for a resource, for example, you might return the clients list as JSON, XML, HTML, etc. it’s a good practice to specify it in the url as well. So decide on your default representation format and expose it as example.com/customers and then add format info to the end of the url if you support others

    example.com/customers.xml
    

    or

    example.com/customers.html
    

    etc.

    Hope it helps!

    I think including IDs in URL may not be a good practice

    Well, there are two main approaches and both have it cons and prons. The first one is using names or short resource desciption instead of IDs. For example, instead of client id you can use its name, example.com/customers/amazon, where amazon is your client name. Another good example of the approach is news sites, if you navigate through cnn.com you will see each article url contains article title http://edition.cnn.com/2016/06/10/middleeast/israel-tel-aviv-shooting/index.html – “Tel Aviv suspect discovered hiding in home of off-duty cop”

    This is great from SEO perspective and the urls become more descriptive and human friendly. But if you have to change your customer name it should change the url and there’s a huge risk of breaking clients. Besides there’s a lot of things to keep in mind while implementing the approach:

    • You should properly validate customer names so they are ok to be added to an url
    • You should either disallow changing customer name or properly handle it by returning 301 (“Moved permanently”) and specifying the new url in the Location header so that the client is aware of the new url
    • etc.

    The main advantage of IDs approach is that urls are always static and you don’t have to bother about the implementation stuff above.

    Both approaches are valid from REST perspective so it’s up to you to decide

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search