Viewing entries tagged
REST

1 Comment

Designing well-formed URIs for your REST Web API

apiThis is a follow up post to “Using HTTP Status Codes correctly in your REST Web API”, and “Using HTTP Verbs correctly in your REST Web API”. Continuing with the theme of RESTful Web APIs, I thought I would touch on the importance of the actual URL/URI part of the Web API. One way we can think of our Web API is as a database exposed through the HTTP layer. Like any good database, we must be careful when designing "the DB model of our Web API". The equivalent to a formal DB Model (ERD for relational databases), is the Resource Modeling that goes into the Web API. Let’s dive right in.

In REST lingo, URI endpoint are referred to as a Resource. From a data standpoint one can think of it as a piece of data describing an entity instance. Here’s some housekeeping rules to keep your Resources neat and clean:

  1. Avoid having your API start at the root domain. The two most common practices are to create a subdomain (such as http://api.mydomain.com), or to have a dedicated base URL different from the root domain (like http://mydomain.com/api). In doing so you ensure the longevity of the URIs assigned to your resource endpoints, and avoid potential collisions with Page URLs you may want to name in certain ways for the website hosted on your root domain. It also helps later on when versioning becomes an issue for a matured Web API.
  2. The resource endpoints should be plural and NOT singular, for example:
    • http://.../api/customers
    • http://.../api/orders
    • http://.../api/products
  3. Use identifiers to locate single elements in the resource URI. An identifier should ALWAYS resolve to the same single resource.
    • http://.../api/customers/123
    • http://.../api/orders/abc77uk
    • http://.../api/books/world-war-z
  4. When designing your resources, the golden rule is “Nouns are GOOD, Verbs are BAD”. Do not use verbs in ANY part of a resource URI.
    • If you see a verb as in a URI, like http://.../api/getcustomers or http://.../api/payfororder, a part of you should die.
    • Do everything in your power to change it, and educate the creators why using verbs is a bad practice.
  5. For non-resource URIs (yes, they do exist) make sure they are CLEARLY functional endpoints.
    • A simple way to do this is to have a special URL path for all functions such as:
      • http://.../api/func/calculate-fees?size=5&weight=8
    • Please don't use non-resource URLs as an excuse to build a RPC style API.
    • Other samples of functional endpoints could be:
      • http://.../api/func/calculateTax?state=fl&amount=10
      • http://.../api/func/randomNumber
      • http://.../api/func/getHash?input=ubniq2

 

As I'm writing this post I cannot think of anything else to add, but this is a good place to start when it comes to the design of your Resource Model for your REST Web API.

Happy coding!

1 Comment

2 Comments

Using HTTP Verbs correctly in your REST Web API

Following up after the earlier post titled Using HTTP Status Codes correctly in your REST Web API, here is one on using the HTTP Verbs from the W3C spec in the "right way" to have a clean REST Web API. Just like the HTTP status codes, there are many more verbs in the HTTP standard that, although they are in theory OK to use for your Web API, you can get by with just a few that helps to keep your API simple, and self-explanatory to its clients.

The full list of HTTP verbs from the spec can be found HERE, but we are going to focus on how to interpret the verbs and the actions that should be executed for each on in the context of a well-defined REST Web API. In the table there is also the result set that standard clients expect when they make requests with such VERBs. To better understand their proper use, we'll use a sample resource endpoint called Users, where the (you guessed it) "Users" of our app are exposed via our Web API.

Resource Sample GET (aka Read) POST (aka insert) PUT (aka update) DELETE (aka delete) PATCH (aka partial update)
api/users Action Gets a list of users Creates a user Batch Update Errors out Batch Update the users only with the attributes present in the request
Return List of users New user No payload, only HTTP Status Code Error HTTP Status Code No payload, only HTTP Status Code
api/users/123 Action Gets a single user Errors out Updates the user Deletes the user Partially updates the user only with the attributes present in the request
Return Single user Error HTTP Status Code Updated user No payload, only HTTP Status Code Updated full user object

 

And this is how you properly use the HTTP Verbs in a REST Web API.

Happy coding!

2 Comments

Comment

Using HTTP Status Codes correctly in your REST Web API

There are like a gazillion HTTP status codes maintained by the W3C and the Internet Assigned Numbers Authority (IANA) in their Official Registry for the HTTP specification. For RESTful Web APIs, even though in theory you could use any of them if the occasion deserves it, I've found that simplifying their use helps in making your API self documenting in nature and simplifies the cases your Web API clients need to consider. Here is my list of 'useful' HTTP Status Codes and how your clients can/should interpret them:

Code Description What it really means for a client of the Web API
200 OK It worked!
201 Created The resource was created OK!
304 Not Modified The client can use the cached version of this resource, because nothing has changed.
400 Bad Request The client did something wrong. The request has bad syntax or cannot be fulfilled.
401 Not Authorized The Web API is requesting the client to authenticate.
403 Forbidden The server understood the request, but is refusing to fulfill it due to restrictions in the client's authorization. Do not try again.
404 Not Found The resource was not found. There is nothing on that endpoint URI.
500 Internal Server Error The author of the service did something wrong. Something went bad on the server. (IOW: the Web API is fucked up)

 

I always include a similar table for my API guidelines page (note I didn't say documentation, cuz a well designed REST Web API should be self documenting)

Happy API designing!

Comment

Comment

A Message to "Enterprise Architects"

Dear Enterprise Architects: The Web was built on a RESTful architecture. Stop trying to invent fancier systems for distributed computing (wink to the herds of ESBs out there).

There isn't a bigger, more proven, more performant, more scalable specimen of distributed computing than the Interweb.

That's right, less is more. Fuck everything else for distributed computing and messaging, even for the "Enterprise".  You need to un-train yourself, stop being a baby and embrace it already, it is the year 2012.

And relax, your Enterprise applications will scale just fine. Now have some cheez,

Best,

Michel Triana

 

World Wide Web - Enterprise Architects

Comment

Comment

WCF WTF!

It gets me when application frameworks tamper with core web concepts of precisely what they are trying to solve. If you have WCF services exposed through any of its different endpoints, you have to do the most ridiculous dancing to get something as simple as the HttpContext. WTF is up with that Microsoft!?!

There are like 10 different ways to access HttpContext and Request Headers, all weird in their own ways, none of them standard, and requiring the callers to add headers in different and specific ways:

  • There is HttpContext (or this.Context or HttpContext.Current): “Gets or sets the HttpContext object for the current HTTP request” This would be the obvious choice, but the WCF team needed to get COMPLICATED! To support this, you have to add extra magic and attributes to your service contracts (read here)
  •  Then we get fancy with something that is not quite the HttpContext the WEB knows and loves, but some new BS called OperationContext (OperationContext .Current). MSDN explains: “Provides access to the execution context of a service method”... but off-course!
  • Also HttpContextBase class according to MSDN “serves as the base class for classes that contain HTTP-specific information about an individual HTTP request”. So, you’d only think that HttpContextBase is the base class of HttpContext right? WRONG!

Hmmm, at this point you think this might be a brain teaser. There may be another 2-3 ways to access data from a similar concepts. If inspecting the HttpContext on the server side is a nightmare, managing headers and contextual http request elements on the client is even worse if your client is using the generated WCF contracts from VS. Here you are either setting something called ‘OutgoingMessageHeaders’ on an http request (like there is something that can be ‘incoming’ during a request), or you are implementing a custom IClientMessageInspector and altering the request before it is sent to the server: what is this the Police Academy (Inspector, pffff)? Why do I need to inspect a message I built? Or why am I forced to do this kind of crap?

This is so frustrating I cannot cope with the unnecessary layers of engineering and noise the WCF team threw over such a simple concept. I have nothing against new and different ways to solve problems, but please don’t call it the same as something that already exists and it’s well defined by the HTTP protocol specification (RFC 2616). PLEASE. DON'T.

I’ll try working around it with Rick Strahl’s post. If I keep having problems, I’ll move out to a different framework, implement my IHttpHandler, or downplay WCF’s capabilities.

Comment