Skip to content

Communicating With REST Services

Overview

Representational state transfer (REST) is a style of software architecture for distributed systems such as the World Wide Web. REST has emerged over the past few years as a predominant Web service design model. REST has increasingly displaced other design models such as SOAP and WSDL due to its simpler style.

The term representational state transfer was introduced and defined in 2000 by Roy Fielding. In enterprise environments REST is often combined with XML to create POX (Plain old XML).

Neuron supports REST, POX and other HTTP services through the Windows Communication Foundation WEB HTTP programming model. There are several resources you can reference to learn more about REST. Here are a few to get you started:

Note: In Neuron, the easiest way to create the HTTP request from an ESBMessage that will be sent to a RESTful web service is to use the Http Client Utility process step or workflow activity. More information about the utility can be found at https://www.neuronesb.com/article/http-utility-json-swagger/

RESTful URLs

A RESTful web service (also called a RESTful web API) is a web service implemented using HTTP and the principles of REST. It is a collection of resources, with these defined aspects:

  • The set of operations supported by the web service using HTTP methods (e.g., GET, PUT, POST, or DELETE)
  • The base URL for the web service, such as http://neuron.com/resources/
  • The local path to the resource, such as /articles
  • The query string containing parameters for the resources operation
  • The Internet media type of the data supported by the web service. This is often JSON, XML or YAML but can be any other valid Internet media type
Note: All of the necessary HTTP properties (method, query, HTTP headers, etc.) to call a RESTful web service are contained in the ESBMessage class’s Http member object. For example, in a C# step in a process, the user would call “context.Data.Http” to access the Http object.

Methods

REST relies on many features of the well-defined protocol HTTP. Primarily, REST reuses the vocabulary of verbs:

   GET
   POST
   PUT
   UPDATE
   DELETE

In Neuron, the HTTP Method can be retrieved or set from the Http object contained in the ESBMessage object by accessing the Method member variable which is of type “string”. In a C# step/activity, this would look like:

Retrieved in a process:

string httpMethod = context.Data.Http.Method;

Set in a workflow (using the “message” workflow argument):

message.Http.Method = "POST";

It is generally recommended, however, to setup the Http object using the Http Client Utility process step or workflow activity.

Base URL

When creating RESTful services using a Neuron ESB Service Endpoint’s Client Connector (which creates a service implementing the binding specified in the Service Endpoint’s General tab), the base URL is the physical URL that all calls to the service will utilize. All resource references will build from the base URL. An example of a base URL is http://servername/rest. In Neuron, the base URL is whats defined as the URL in a Client Connector.

Similarly, the Service Connector’s URL in a Neuron ESB Service Endpoint is what will be used to construct the final URL to call. The format of the final URL will usually be “<the URL in Service Connector>/<local path from ESBMessage>?<query string if Http.Method == “GET”>”. This is UNLESS an Http Client Utility process step or workflow activity is used and a valid URL (i.e. starts with “http://” or “https://”) is specified in the utility as opposed to just a local path. In the case where a URL is supplied in the utility, the utility’s URL will override the Service Connector’s URL (the LocalPath string in the ESBMessage object will still be appended to the overridden URL).

Local Path

The local path of a RESTful URL is the portion of the URL after the base URL, but before the query string identifier ( “? “). In Neuron, the local path can be retrieved or set from the ESBMessage object’s LocalPath member variable, which is of type “string”. Take note that the LocalPath variable is NOT in the Http object, but in the ESBMessage object. The value of this property will always contain a leading slash “/ “. An example of a local path is “/users”. Getting or setting it in a C# process step is done by assigning or retrieving “context.Data.LocalPath”.

Query Strings

A query string is the part of a URL that contains data to be passed to the RESTful service. The data in the query string is represented as name-value pairs. A typical URL containing a query string is as follows:

http://server/path/program?query_string

The format of a query string is:

field1=value1&field2=value2&field3=value3...

The query string is composed of a series of field-value pairs.

The field and value of each field-value pair is separated by an equals sign. The equals sign may be omitted if the value is an empty string.

The series of pairs is separated by the ampersand, ‘&’ or semicolon, ‘;’.

Some characters cannot be part of a URL (for example, the space) and some other characters have a special meaning in a URL: for example, the character # can be used to further specify a subsection (or fragment) of a document; the character = is used to separate a name from a value. A query string may need to be converted to satisfy these constraints. This can be done using a schema known as URL encoding.

In particular, encoding the query string uses the following rules:

  • Letters (A-Z and a-z), numbers (0-9) and the characters ‘.’,’-‘,’~’ and ‘_’ are left as-is
  • SPACE is encoded as ‘+’ or %20[citation needed]
  • All other characters are encoded as %FF hex representation with any non-ASCII characters first encoded as UTF-8 (or other specified encoding)

In Neuron, the query string can be retrieved or set from the Http object’s Query member object which is of type IDictionary<string, string>. The “field” of a field-value pair will be assigned as the key of the Dictionary entry and, similarly, the “value” will be assigned as the value. The part of the URL after the question mark “? ” is the query string. An example of a URL containing a query string is “http://baseurl/theLocalPath?user=123&basket=23544dr12wR” with “user=123&basket=23544dr12wR” being the query string.

To add a field-value pair to the Query IDictionary object using a C# process step would look like:

context.Data.Http.Query.Add("theField", "theValue");

The Http Client Utility can also be used to add a query using the URL Parameters tab.

REST in Neuron

Neuron supports REST through client connectors and service connectors using the REST binding. Processes are used to transform REST requests to SOAP or adapter-based requests and non-REST requests into REST requests. There are a number of message properties available to assist in this translation.

REST Connectors

Setting up a REST Connectors is straightforward. Create a new Service Endpoint and on the General tab of the Service Endpoint choose REST for the binding:

Switch to the Client Connector tab, choose the Publisher and Topic you are going to use, enable the connector and add the URL that will be the base of the REST URLs hosted by that endpoint:

In this example we are not appending a “/ ” to the Client Connector URL. Depending on your scenario you may need to experiment with the base address. Many times you will control the target service and URL generation because you will be talking to internal services or sometimes you may be mediating between a REST Client Connector and a SOAP Service Connector in which case there are no back end URLs.

To create a Service Connector, switch to the Service Connector tab, select a subscriber and enter the base URL of the target REST service:

REST URLs in Neuron

Neuron allows you to work with the URL directly and get access to the verb and the data sent in the HTTP request. By combining Processes, Client Connectors and Service Connectors and understanding how you can access HTTP verbs in Neuron you can accomplish a wide array of REST scenarios.

The URL you host in a REST endpoint in Neuron allows for a high degree of dynamic behavior because everything after the URL entered into the Client Connector URL property is allowed to be addressed through the connector.

For example if you configure a Client Connector with a URL of http://servername/rest the following URLs would all be accepted by the Client Connector

Important Neuron HTTP API Properties

Neuron provides access to several properties that enable you to create REST integrations. These properties are set by the Client Connector when a REST request is received and used by the Service Connector when sending REST requests:

ESBMessage Member ObjectsDescription
esbMsgObj.Header.ToContains the entire URL of the request.
esbMsgObj.LocalPathContains the portion of the URL between the end of the base URL defined in the service endpoint and the question mark “? ” provided in the query string.
esbMsgObj.Http.MethodContains the HTTP Verb GET, POST, PUT, etc. A list of valid values can be found here – http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.
esbMsgObj.Http.QueryThe Dictionary that contains the field-value pairs that query string of the request is constructed from.
esbMsgObj.Http.Headers.ContentTypeContains the content type of the message body. A list of valid values can be found here – http://en.wikipedia.org/wiki/Mime_type.
esbMsgObj.SetProperty(“MessageProperty”, “WebBodyFormatMessageProperty”, “Raw”)Specifies the message format to map the message body to. Neuron only checks for the value Raw. All other values are ignored. When not set to Raw, the message is mapped to XML.
esbMsgObj.Http.StatusCodeContains the response code of the REST service call. A list of valid values can be found here – http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.

One addition property used is context.Data.Header.Binary. When sending binary message data over REST requests you need to set this property to true.

Handling POSTs and GETs With a Reusable Pattern

The pattern presented below shows how you can leverage Neurons Processes to create a Client Connector that accepts POSTs or GETs and then leverages the Neuron Publishing system to flexibly dispatch requests and responses.

POSTs in the Method value will represent sending data that does not expect a response and GETs will represent queries.

These are not hard and fast rules because Neuron allows nearly any processing to occur here so you can use PUT in place of POST for example. The important thing is to understand what the pattern accomplishes.

The Process is intended to be connected to the Client Connector Partys On Client Publish.

The first step in the Process is a Decision Step. It contains the code

return context.Data.Http.Method == "POST";

This causes processing to go down either the POST branch or the GET branch. The second step in both branches is a dispatching code step. This step involves using any code you desire to set the topic.

//Code to decide topic to send on. Can be based on  "To ",  "QueryString " or body of the message
context.Data.Header.Topic = {topic value figured out in code}

Next, you use the Publish Step to send the message to the bus inline. This allows you to create a highly decoupled solution. The Publish Step allows the ESBMessages Topic property to be set one of two ways. The Publish Step property that contains this value is the SelectorType. One choice off SelectorType is called Constant and choosing this will cause the TopicSelector property to present a drop down. The other SelectorType is code. This is the one we will use. This will cause the TopicSelector to present an ellipsis into which code can be entered. The code you will enter is:

message.Header.Topic = message.Header.Topic;

That may look a bit strange but this allows us to basically say I already set this value dynamically use it. The most common use of the Publish Step is publishing on a known topic on a different Topic than the message came in on so the options are friendliest to the usage.

We could have avoided this seeming redundancy by including the message dispatching logic in this Step and eliminating our dispatch Code Steps. This is actually why the code TopicSelector is a full code block. It is decoupled in this example because the author feels it is a cleaner approach.

The final property on the Publish Step is set the Semantic property. The default is Multicast. This value is designed for asynchronous messaging and should be set on the POST branch because we do not expect to return data from this branch. But, the GET branch is expected to return data so we will use a value of Request

Next, on the POST branch only add a code step to return an empty message (At the protocol level there is no such thing as HTTP requests that do not expect a response so we will return an empty body and WCF will take care of setting the HTTP headers)

//set empty response for POST
code.Data.FromString( " ");

In both braches, set the HTTP Response status code:

// Set the response code, 200 - OK
context.Data.Http.StatusCode = System.Net.HttpStatusCode.OK;

Finally, we use the magic of adding a Cancel Step as the final Step used in a process used by the Client Connectors Party. This causes Neuron to abort message processing and return whatever message value is available. In the case of a POST this will be an empty message and in the case of a GET it will be the value returned by the Subscriber which could be a Service Connector, Adapter or your own custom service that is using the Neuron API.

Was this article helpful?
Dislike 0
Previous: Service Endpoints