REST in Pieces

JSON, REST API, Ensemble

A beginners guide to develop Ensemble RESTful web services.

Background

Before you start reading this short introduction please go through the on-line documentation of Ensemble with special attention to chapter “Creating REST services and clients with Ensemble”.

The approach in the documentation is undisputable the fastest and easiest way to create RESTful services. As a beginner I went through the documentation and I had several questions. This short article is listing those questions plus my humble answers.

When I refer to documentation I mean Ensemble 2016.2 and onwards.

What does an Ensemble service make RESTful?

We all learnt, that an Ensemble service becomes any specific (like file service) by binding a specific inbound adapter to generic service. For example EnsLib.HL7.Service.Standard in combination with EnsLib.File.InboundAdapter constructs a HL7 file service. OK. Even if this logic did not apply entirely to SOAP services this is a common way how services are built.

But is this “standard_service+specific_adapter” schema works with RESTful services? Not quite. The documentation say:

To develop a REST service you extend the class EnsLib.REST.Service. … Implementing a REST service is an extension of implementing the %CSP.REST class and implementing an HTTP service.

Great. Even easier than I thought. By subclassing EnsLib.REST.Service I got everything for free. We are done with answering the question: any subclass of EnsLib.REST.Service is an Ensemble RESTful service. It is that straight. Isn’t it?

It seems that simple until you do not read the following note:

In most cases, we recommend that you use Ensemble’s CSP port and not a special port. Using Ensemble’s CSP port allows you to use a full-featured web server to provide robustness and security.

Fine. I stay with the recommendation. But is security the only difference? Well, please read the whole section after the cited note.

At the end of the section you will find the proper instructions what exactly to do instead of subclassing EnsLib.REST.Service.

You can add the EnsLib.REST.Service business service directly to the production using the management portal, but you can only indirectly add the %CSP.REST subclass. To add it indirectly, follow this procedure:

  1. Add a custom business service that is a subclass of Ens.BusinessService to the production. This subclass implements the OnProcessInput() method.
  2. Call the Ens.Director.CreateBusinessService() method from the %CSP.REST subclass. The CreateBusinessService() method enables the custom business service and returns a pointer to it.
  3. Use the pointer to the business service to call the OnProcessInput() method.

So the Ensemble RESTful service is a single concept but implemented in to two pieces (classes). Thus the answer to the question: any generic service can be RESTful. Or: a single subclass of %CSP.REST can populate (almost) any Ensemble service as a RESTful web service even if the service class is not implemented in the notion of neither RESTful nor web services.

How does the %CSP.REST linked to configuration items?

Surely there are endless variations to link somehow the %CSP.REST subclass to the name of the production item started by the Ens.Director.CreateBusinessService(). The documentation has a long recommendation. You will find at the section Defining the URL Using UrlMap and EnsServicePrefix. The bottom line is: your RESTful service URL should look like /{{cspapproot}}/{{ensconfigitemname}}//{{restparameters}}. That middle piece in the URL links %CSP.REST subclass to the configuration item.

How many service classes are there?

Since one service in the Ensemble way of programming is able to process a single message type, you ought to have as many service classes in your class library as many distinct message types you have. It means that service classes are implementing common message processing pieces of a web service.

How many service instances are there?

Is not it the same as the service classes? No. The same service class can be instantiated in the same production under different names depending on various conditions. Like in a HL7 production. Trigger events, message sources, message priorities can all be divider to identify the pieces of an Ensemble production.

How does the HTTP request be built?

RESTful services are at the end HTTP services. HTTP has several ways to carry information pieces across the network. Those pieces are created by the client as part of the HTTP request generation. On the server side those pieces are pulled again together to construct the Ensemble request. What are the options?

  1. Pieces are encoded into URL path. The information pieces are positional parameters of the URL path. This is the very RESTish parameter passing. If it were SOAP we would call this style as RPC. The procedure parameters are passed to the service within the URL path. This style however suffers from several limitation. Most importantly for complex request the URL syntax is a limitation.
  2. Pieces are encoded into URL query part. Nearly the same as the URL path encoding, but instead of having the data piece in the path (before the ?), we put it to the query (after the ?). What is the difference? If you have data piece which is mandatory, you can put it into URL path. But if you have optional data pieces, it is better to put it into the query part. It is simply because remember the URL path is a positional binding, while query is a key, value pair. If you have an empty field in URL path, it would look like this “/some/url/path//with/emty///pieces”. While if query holds the data it could be like this “/some/url/path?qp=&data=&”.
  3. Pieces are encoded into form data. That is little more advanced then query part encoding. As a matter of fact on the server side there is no visible difference.
  4. Pieces are hold by the HTTP request body. For document type of data exchange this is the best option. On the server side it is projected as a stream. When we talk about true RESTful interface we should expect the stream holding a JSON string.
  5. Pieces are hold by file attachment. It is surly the only option when you have multiple binary attachments in a single request.
  6. AND/ OR any combination of the above options…

How do I process the HTTP request?

Obviously as we have different solutions to build the request, we have options to process the request.

  • Processing URL path pieces. The %CSP.REST class provides the mechanism to define positional parameter in the URL path and map it to the static class method call’s argument. From the first glance it looks like if it were passed by name, but in fact you can use any time in the method signature the variable number of arguments syntax (argv…) which means positional passing again. As you know the positional argument passing gives you a single argument vector instead of multiple parameters. It requires special attention in the method implementation, but gives a great flexibility to the programmer. In the service class OnProcessInput method the pInput argument will hold an argument vector.
  • Processing query path or form data pieces. Those pieces are passed within the %request.Data multidimensional property. Please refer to the %CSP.Request class documentation how to access the data inside the property.
  • Processing HTTP request body stream. If the content type of the message body is “application/json”, then we are in a luxurious position, because we just need to read the %request.Content stream property and parse to a dynamic object.
  • Binary attachment? Yes, that piece is missing…

Since any combination is valid, there might be situation when you have all this pieces to construct an Emsemble request object.

How do I test my service?

It has two distinct pieces. How do I generate test messages & how do I monitor the network traffic. The second piece can be solved easily. Since all requests are going through the standard CSP gateway you can turn HTTP Trace ON at the System Management Portal. But how about the message. The documentation examples are using “curl”. It is a command line tool available for (almost) any platform. Including Windows10 too. Surely for those who are using terminal window or command line interface daily it is an option. Some alternatives:

  • soapUI if you are already familiar with. It does RESTful…
  • Your preferred browser. These days browsers amuse developers with testing, debugging, tracing tools.
  • A static HTML page. It can do GET easily testing URL encoded parameter passing or can do POST for form data.
  • HTML page with AJAX. With AJAX you can do GET, POST, PUT, you can pass URL encoded, form data as well as HTTP request body. AJAX is standard piece of most of the popular JavaScript convenience libraries such as jQuery, AngularJS.

Is it REST or RESTful?

I had to ask this question because sometimes it is important to talk a language which is talked by the industry. Now REST is a concept while RESTful is an implementation which respects the concept. So I think the answer is RESTful, because our implementation respects every piece of the REST concept.
 

Stey tuned. I'll be back shortly with other articles.

  • + 9
  • 0
  • 1511
  • 6

Comments

Great article, however, I strongly disagree on the testing tools choice. Curl is not really the option, as CLI tools are really not the best for json editing. Upon the rest of your testing suggestions, I think there are better alternatives, such as:

  • REST clients: “Advanced REST Client” for Chrome and “REST Client” for Firefox, some are also available as a standalone applications
  • Debugging web proxies: Charles, Filddler etc. for the rare cases where REST clients do not offer enough information

Another great alternative REST client is Postman - I used Advanced REST Client for a while before switching to it. I think the motivation for switching was better HTTP redirect handling in Postman.

I agree, Postman is a great tool.

If you want to document your REST interface, take a look at Swagger. You can generate an HTML documentation for your interface and test each call directly. 

Or have a look at Restlet which can produce Swagger as well as RAML, it's still undetermined which will be the defacto standard for API documentation.

Thanks for the comments. This article is mainly for beginners and focusing on how to build RESTful services. Yes, selecting the right testing tool could be important. But let us help the beginners to buld their first service, let them try (using something) and once they are able to "fly" write them an article "Selecting the best tool for  testing RESTful services".