Forwarding Requests in a REST Service
Tags: xml, csp, json, practice
Published: 2021-05-26 14:45:20

One useful feature of our REST framework is the ability for a dispatch class to **identify request prefixes and forward them** to another dispatch class. This approach of modularizing your URL map will improve code readability, enable you to easily maintain separate versions of an interface, and provide a means to protect API calls that only certain users will be allowed to access.

### Overview

To set up a REST Service on your Caché instance, you need to define a dedicated CSP application and create the associated **dispatch class** that handles incoming requests. The dispatch class extends %CSP.REST and will include an XData block that contains your URL map. This tells the system which method to call when a particular request is received.

For example:

<pre><span style="color:#0000CD;">XData</span> UrlMap [ <span style="color:#0000CD;">XMLNamespace</span> = <span style="color:#800080;">"http://www.intersystems.com/urlmap"</span> ]
{
&amp;lt;<span style="color:#0000CD;">Routes</span>>
  &amp;lt;<span style="color:#0000CD;">Route</span> <span style="color:#A52A2A;">Url</span>=<span style="color:#008000;">"/orders"</span> <span style="color:#A52A2A;">Method</span>=<span style="color:#008000;">"GET"</span> <span style="color:#A52A2A;">Call</span>=<span style="color:#008000;">"GetOrders"</span>/>
  &amp;lt;<span style="color:#0000CD;">Route</span> <span style="color:#A52A2A;">Url</span>=<span style="color:#008000;">"/orders"</span> <span style="color:#A52A2A;">Method</span>=<span style="color:#008000;">"POST"</span> <span style="color:#A52A2A;">Call</span>=<span style="color:#008000;">"NewOrder"</span>/>
&amp;lt;/<span style="color:#0000CD;">Routes</span>>
}</pre>

The &lt;<span style="color:#0000CD;">Route</span>> elements define the various requests that the service will handle. A GET request for the resource <span style="color:#008000;">"/orders"</span> will call into the classmethod <span style="color:#008000;">"GetOrders"</span>. A POST request made for the same resource will instead call into the <span style="color:#008000;">"NewOrder"</span> method.

It’s important to note that the CSP application name is not considered as part of the requested resource name in our URL map. Consider a request made to the address:

<pre>http://localhost:57772/csp/demo/orders</pre>

If our CSP application is called <span style="color:#008000;">"/csp/demo"</span><span style="color:#000000;">,</span><span style="color:#008000;"> </span>then the only segment of the request handled by the dispatch class is what comes after the application name. In this case, that is <span style="color:#008000;">"/orders"</span>.

### Request Forwarding

Rather than call a method inside the dispatch class, the other option for your URL map is to forward all requests matching a particular prefix to a different dispatch class.

This is done using the &lt;<span style="color:#0000CD;">Map</span>> element in the UrlMap section. The element contains two attributes, **<span style="color:#A52A2A;">Prefix </span>**and **<span style="color:#A52A2A;">Forward</span>**. If the request URL matches one of the prefixes, we send the request to the specified dispatch class for further processing.

For example:

<pre><span style="color:#0000FF;">XData</span> UrlMap [ <span style="color:#0000FF;">XMLNamespace</span> = <span style="color:#800080;">"http://www.intersystems.com/urlmap"</span> ]
{
&amp;lt;<span style="color:#0000FF;">Routes</span>>
  &amp;lt;<span style="color:#0000FF;">Map</span> <span style="color:#A52A2A;">Prefix</span>=<span style="color:#008000;">"/shipping"</span> <span style="color:#A52A2A;">Forward</span>=<span style="color:#008000;">"Demo.Service.Shipping"</span>/>
  &amp;lt;<span style="color:#0000FF;">Route</span> <span style="color:#A52A2A;">Url</span>=<span style="color:#008000;">"/orders"</span> <span style="color:#A52A2A;">Method</span>=<span style="color:#008000;">"GET"</span> <span style="color:#A52A2A;">Call</span>=<span style="color:#008000;">"GetOrders"</span>/>
  &amp;lt;<span style="color:#0000FF;">Route</span> <span style="color:#A52A2A;">Url</span>=<span style="color:#008000;">"/orders"</span> <span style="color:#A52A2A;">Method</span>=<span style="color:#008000;">"POST"</span> <span style="color:#A52A2A;">Call</span>=<span style="color:#008000;">"NewOrder"</span>/>
&amp;lt;/<span style="color:#0000FF;">Routes</span>>
}</pre>

A GET or POST request for <span style="color:#008000;">"/orders"</span> will be handled directly by this class. However, requests matching the prefix <span style="color:#008000;">"/shipping"</span> will be redirected to the dispatch class <span style="color:#008000;">Demo.Service.Shipping</span>, which has its own URL map:

<pre><span style="color:#0000FF;">XData</span> UrlMap [ <span style="color:#0000FF;">XMLNamespace</span> = <span style="color:#800080;">"http://www.intersystems.com/urlmap"</span> ]
{
&amp;lt;<span style="color:#0000FF;">Routes</span>>
  &amp;lt;<span style="color:#0000FF;">Route</span> <span style="color:#A52A2A;">Url</span>=<span style="color:#008000;">"/track/:id"</span> <span style="color:#A52A2A;">Method</span>=<span style="color:#008000;">"GET"</span> <span style="color:#A52A2A;">Call</span>=<span style="color:#008000;">"TrackShipment"</span>/>
&amp;lt;/<span style="color:#0000FF;">Routes</span>>
}</pre>

### URL Routing Breakdown

To demonstrate how each component of the requested URL factors into what method is finally called, we will break down a request for the following address:

```
http://localhost:57772/csp/demo/shipping/track/123
```
|http://         |The protocol used for the request.|
|----------------|----------------------------------|
|localhost:57772 |The server that we connect to.    |
|/csp/demo/shipping/track/123 | The resource being requested.|
|/csp/demo |The CSP application name.A dispatch class is defined for the application, route the request there.|
|/shipping/track/123| The resource segment sent to the first dispatch class.|
|/shipping |The prefix that matches the <Map> element in the URL map.Redirect to the Demo.Service.Shipping class.|
|/track/123| The resource segment sent to the second dispatch class.Matches the route "/track/:id".Call the method TrackShipment(123).|

### Motivation

* ***Source control —***  Separating your REST API into multiple classes will reduce the overall size of each class, which in turn will help keep your source control history concise and readable.  
* ***Versioning —*** A simple way to support multiple versions of an API simultaneously is to use forwarding. A single dispatch class could forward requests matching the /v1 or /v2 prefixes to a dispatch class implementing that version of the API. The REST API at the heart of Atelier, our new IDE, uses the same versioning scheme. 
* ***Security —*** If your API needs to have routes that are restricted to certain users — for example, to allow only administrators to make certain types of requests — it makes sense to isolate these routes in their own class, then forward requests using a particular prefix. If the second dispatch class defines an __OnPreDispatch__ method, its code will be executed before processing each request. The service can use this to check a user’s privileges and decide whether to continue processing or cancel their request.