Posts Tagged ‘REST’

Hand manipulating gears

Choosing a Web API: REST, Remote Procedural Call or Hybrid

REST is a popular architectural style that has been the go-to design for web-based APIs for years. The style has defining constraints, but it is not a protocol and there is no official standard. REST is like the pirate’s code in the Pirates of the Caribbean movie franchise, in that REST “is more what you would call guidelines than actual rules.” As such, not everyone follows the guidelines exactly or interprets them the same way.

This can lead to some confusion and debate as to what is and is not considered RESTful. At the same time, one can look at this flexibility as an opportunity to pick and choose what will work best for their needs. In this article, we briefly discuss some web API design options and explore some of their strengths and shortcomings.

What REST is – and isn’t

For some, REST simply means using a service that is not SOAP. SOAP is another widely used protocol, but some stay away from it due to its complexity and the extra overhead that it requires. You would be hard pressed to find a REST-related article where SOAP is not mentioned. You will likely find comments about how great REST is because REST uses JSON and SOAP uses XML.

People often mistakenly think that REST is defined by the JSON language format, and when they say they want a RESTful service what they really mean is they want a service that supports JSON. REST is not as simple as that, and it is not confined to any one language format: it is an architectural style and not a specific protocol. Conversely, JSON is not exclusive to REST, as JSON is also available in Remote Procedural Call (RPC) APIs.

So, with that out of the way, the rest of this article will assume that the reader is familiar with the general style of REST. If you wish to learn about REST in more detail then feel free to read the dissertation it was based on – or if you’re not into heavy reading, check out the REST wiki.

Comparing three web API options

Now, let’s look at three different approaches you can use for web APIs:

  • REST – Representational State Transfer (REST) web APIs are “resource” oriented. RESTful APIs synergize well with CRUD applications and other forms of data resource management and manipulation.
  • RPC – Remote Procedural Call (RPC) web APIs are “action” oriented. They enable the user to call a remote method to complete an action as though it were local. This is similar to importing and using the methods from a local library API.
  • Hybrid – Hybrid designed web APIs incorporate both the RESTful style and RPC-based design methods. Some RESTful APIs will include RPC design to add action methods where strictly RESTful resource-oriented methods are not appropriate.

Since REST is resource oriented it is also useful for resource discovery. For example, if a Service Objects client was interested in all the cities or ZIP codes for a state then a RESTful API for discovering those resources and drilling into them for details would be ideal. This approach will also work well for suggestion and IntelliSense applications where several queries to find an address would be acceptable.

By comparison, users looking for address validation could find that having to make several queries would be cumbersome – especially if their data is incomplete or partially invalid. Most of our users do not always have complete data, and lean on us heavily to parse through and correct any garbage or mistakes to fill in the gaps and return an intuitive and standardized response.

RESTful example: Address Validation

Let’s briefly explore what creating a RESTful address validation service would look like. We’ll start by coming up with a way for the user to submit an address for validation.

For this exercise, the theoretical service will be hosted on the following domain and path.

Domain: example.serviceobjects.com

Path format: /AddressValidation/{State}/{City}/{ZIP}/{AddressLine1}/{AddressLine2}

The above format lends itself more to address discovery and would be better suited with a /FindAddress path name; however, this application’s primary job is validation and not discovery so let’s continue.

Let’s test the service using the Service Objects office address as an example.

Path example: /AddressValidation/CA/Santa Barbara/93101/27 E. Cota St #500/

Unfortunately, the above example will fail to validate correctly due to the pound/hashtag (#) character. We know that the # symbol is a special URL character and that it is used as a fragment identifier. Commonly referred to as anchor in HTML. Its inclusion means that the URL path is prematurely terminated at the # symbol.

In this case, the API can respond in a few ways. It can return an HTTP Status code of 400 (Bad Request), but that isn’t too helpful to the user. It can also accept the request, but since the service is unable to see anything past the # symbol, the full address will not be validated. This is problematic, not only because the full address is not being validated, but what would be an acceptable response from the service? Validating the address as-is would be misleading to the user, and the service itself is unaware that parts of the address are missing. In the end, for this example, it would be best for the service to return the 400 status code for safety.

Now let’s try a different path format:

Path format: /AddressValidation/{State}/{City}/{ZIP}/{AddressLine1}/{UnitNumber}/{AddressLine2}

Path example: /AddressValidation/CA/Santa Barbara/93101/27 E. Cota St/500/

The above path format and example work, but it requires the user to parse out the apartment number from the address beforehand, and it is still susceptible to malformed requests due to special URL characters.

As we have just demonstrated, the path parameter approach has some shortcomings. More details and examples are available in a past tutorial. Fortunately, REST is not limited to one way of making requests; however, depending on one’s interpretation this is where this service and many others start to deviate from RESTful guidelines.

Foregoing the path parameter approach entirely, we could use query string parameters or POST requests.

Query string example: /AddressValidation?AddressLine1=27 E. Cota St #500&AddressLine2=&City=Santa Barbara&State=CA&PostalCode=93101

In the above example, the query string parameters can be URL encoded, and there is no fear that the full address will not be passed in. There is also the option to use POST, but using POST instead of GET to read a resource is generally not done as it goes against REST guidelines. However, it is not uncommon to see many services use POST in ways outside of the REST guidelines.

For presentation sake, let’s continue with our example using POST and JSON.

JSON POST request: 

A strictly RESTful response would be as simple as an HTTP 200 status code with a response like this:

If we provided an invalid address, for example by changing the suite number from 500 to 5,000 which does not exist, the RESTful response would then potentially return an HTTP status code of 404 with an output of:

The above output examples are too simplistic and not informative enough. The service could return a status description of “Address Not Found”, but the user is still left with very little information to work with. Our users rely on our services to not just validate their data but to also help inform them on how to proceed with using their data.

Following the RESTful style guidelines, the output could also contain an Address ID that can be used to reference the address and list details for it.

This RESTful style is not quite user friendly in that it requires the user to perform two queries: one to verify the address, and another to retrieve details for it. A big part of the problem stems from REST being “resource” oriented whereas Validation and Verification services are “action” oriented; therefore, lending themselves more towards the RPC-based design.

That’s not to say that the RESTful service cannot be made more user friendly. A hybrid approach can be taken, and the service could be expanded to be more informative by adding parameters to retrieve additional data so that only one request query is needed.

Output:

However, using an RPC-based design and forcing it to try and conform to the RESTful style doesn’t necessarily lead to a better user experience.

Why flexibility is important

REST, RPC and hybrid designs each have their own merits and uses. It’s important to choose a design that works best for the given situation. That’s why Service Objects chooses a hybrid approach for our services that leans more toward the RPC-based design, since it suits the action-oriented usage. With validation services there are often many gray areas and edge cases to deal with that work best with custom action-based verb commands.

In a RESTful style, custom verb commands are to be avoided, and some would argue that any use of them would, strictly speaking, not be REST. However, many services do make use of both in a hybrid approach and even Google’s API Design Guide states that , “both RPC APIs and HTTP REST APIs are needed for various reasons, and ideally, an API platform should provide best support for all types of APIs.” So, whether you want to use HTTP GET, POST or SOAP with XML or JSON, the Service Objects DOTS Web Services have you covered.

No image, text reads Service Objects Tutorials

Path and Query String Parameter Calls to a RESTful Web Service

It’s important to remember that REST is an architectural style and that it does not have an official standard. As such, the question on how to call a REStful web service will often arise. If the service you are calling supports more than one way of being called, then which way should you choose? The short answer is the one that works best for you, and by works best for you I don’t simply mean the one that you feel most comfortable using (although that is an important factor). For the purpose of this article, we will focus on path parameter calls and how they compare to query string parameter calls, two deceptively similar styles. There are inherent differences between path parameters and query string parameters that you should consider before choosing one over the other.

A RESTful web service should behave the same regardless of how it is called, and as long as the same input values are provided the service will return the same result values every time. So why choose one format over another?

If you are unfamiliar with path parameters, then simply put, a path parameter template is one where the parameter values are embedded in the URL path.

Path parameter example:

http://domain/resource/verb/value1/value2/value3

Query string parameter example:

http://domain/resource/verb?key1=value1&key2=value2&key3=value3

The above examples are rough, but they get the point across. Notice that in the path parameter example the variable values are embedded in the URL path, whereas in the query string parameter example the variable values are provided in the query string.

Path parameters have gained popularity as being more human readable and easier to understand as the path template lends itself to a natural progression of drilling into data resources. Some services offer path parameters specifically for this reason. The user experience can be likened to having a direct connection to the data resource and it is often useful for simple lookup services where no data transformation/refinement occurs, or is needed. Path parameters can enable a service to be called in a distinctive style and, depending on the functionality of the service being called, the path template can take on many forms.

Here are some common examples:

http://domain/resource/format/noun/verb/value

http://domain/resource/noun/value1/value2

http://domain/resource/noun/verb/value1?format=formatvalue

The above examples add the noun and format values, where the noun can help make the service request more descriptive, intuitive and easier to understand. The format value, when available, is commonly used to tell the service what type of response format to return, typically either json or xml.

This is not to say that a service that is called on using query string parameters cannot be designed to be as descriptive and intuitive as a path parameter service.

Caveats to look out for when using path parameters:

  • Order matters: Unlike query string parameters, the order in which the path parameter values are given must correspond to the format dictated by the URL path. For example, if the service path dictates “/resource/format/noun/verb/value” then you cannot interchange it with “/resource/verb/format/value/noun/”.
  • Path parameter values cannot be omitted: Unlike query string parameters you cannot omit a value in path parameters because doing so would mean changing the URL path. The only exception is the final parameter value in the URL path. If the path format is “/resource/verb/value1/value2/value3”, and you want to omit value1 then “/resource/verb//value2/value3” will not work because it is the same as “/resource/verb/value1/value2/”. In which case, you have inadvertently omitted value3. If you omit enough values then you will end up with a malformed URL.
  • Reserved HTTP characters: such as “:”, “/”, “?”, “#”, “[“, “]” and “@” – These characters and others are “reserved” in the HTTP protocol to have “special” meaning in the implementation syntax so that they are distinguishable to other data in the URL. If a variable value within the path contains one or more of these reserved characters then it will break the path and generate a malformed request. You can workaround reserved characters in query string parameters by URL encoding them or sometimes by double escaping them, but you cannot in path parameters.

These are just some simple examples of how a path parameter URL request can differ from a query string parameter request. Overall, it is important to note that regardless of where the parameter variable values are placed, either in the path or in the query string, both styles must conform to the HTTP protocol. For some services, path parameters offer a more descriptive and distinct style that enforce a specific way of querying resources, whereas old-fashioned query string parameters offer greater flexibility and ease of use at the cost of being potentially less descriptive and intuitive.