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:
-
Customer profile:
example.com/customers/{customer-ID}
-
Orders for {customer-ID}:
example.com/customers/{customer-ID}/orders
-
Tickets for {order-ID}:
example.com/customers/{customer-ID}/orders/{order-ID}/tickets
-
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:
-
Namespacing features behind the username like
example.com/{username}/followers
are great solutions for public features that belong to each user individually.
-
Private things, such as account settings, should never be namespaced behind the username, and should just appear after
/account
or/settings
. -
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.
-
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.
-
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.
-
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.
-
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
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:
Orders for {customer-ID}:
Tickets for {order-ID}:
Messages for {ticket-ID}
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:
See all tickets for a customer:
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 toexample.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.
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
or
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 othersor
etc.
Hope it helps!
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
, whereamazon
is your client name. Another good example of the approach is news sites, if you navigate throughcnn.com
you will see each article url contains article titlehttp://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:
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