FRAMES | NO FRAMES Description | Schema | Resources | Operations
Service Extension
URL http://<service-url>/exts/<extensionName>
Parent Resource Map Service

Description

Organizations extending ArcGIS Server via Server Object Extensions (SOEs) want to expose their custom GIS functionality through the Web APIs. The ArcGIS REST API which exposes out-of-the-box ArcGIS Services to the Web APIs can be extended to provide the same support for custom SOEs as well - exposing GIS functionality contained in the SOE as resources and operations.

Note that at 10, only Map Service extensions are supported.

To expose an SOE from REST, developers need to implement the IRESTRequestHandler interface. This can be implemented in various languages including Java, C# and C++. Details on implementing and registering custom SOEs are available in the documentation of ArcGIS Server for Java and ArcGIS Server for .NET respectively. Once implemented and registered with a service, a custom SOE will be accessible from the REST API. It will also be simultaneously available in the Services Directory for users to browse the various resources and operations exposed by the SOE.

In this document we'll talk about SOEs from the perspective of the REST client. To that effect, we'll distribute our discussion into 3 sections:

Schema

The resource and operation hierarchy of an SOE is based on the schema specified by the SOE. The REST handler invokes the getSchema() method on the IRESTRequestHandler interface to get the SOE schema. This schema should be returned as a JSON formatted string. From the REST API, this schema is available by specifying a query parameter f=schema on the root SOE resource:

http://<service-url>/exts/<extensionName>?f=schema

Let's look at a few example schemas to understand how one specifies the resource and operation hierarchy.

Schema 1 - SOE with 1 operation

{
  "operations" : [ "buffer" ]
}

In the simplest case, an SOE exposes a single operation. From the perspective of the REST API, this SOE exposes 2 URLs - the root SOE resource and the buffer operation:

http://<service-url>/exts/<extensionName> //root SOE resource
http://<service-url>/exts/<extensionName>/buffer //buffer operation

Schema 2 - SOE with multiple operations

{
  "operations" : [ "buffer", "near" ]
}

Since the operations property in the schema is an array, one can specify multiple operations. From the perspective of the REST API, this SOE exposes 3 URLs - the root SOE resource and the buffer and near operations:

http://<service-url>/exts/<extensionName> //root SOE resource
http://<service-url>/exts/<extensionName>/buffer //buffer operation
http://<service-url>/exts/<extensionName>/near //near operation

Schema 3 - Operations with parameters and supported output formats specified

{
  "operations" : [
    {
      "name" : "buffer", 
      "parameters" : ["location", "distance"], 
      "supportedOutputFormats" : ["json", "amf"]
    },
    {
      "name" : "near", 
      "parameters" : ["location", "distance", "lookingFor"], 
      "supportedOutputFormats" : ["json"]
    }
  ]
}

This exposes the same URLs as the ones in Schema 2. The only difference is that instead of specifying only the operation names, this specifies some more info pertaining to each operation. This helps the Services Directory provide a more helpful form to the user for each operation as we'll discuss later.

Schema 4 - Child resources

{
  "name" : "MyMapServiceExtension",
  "operations" : ["export", "identify"],
  "resources" : [
    {
      "name" : "metadata"
    },
    {
      "name" : "layers",
      "isCollection" : true,
      "operations" : ["query"],
      "resources" : [
        {
          "name" : "features",
          "isCollection" : true
        }
      ]
    }
  ]
}

In addition to operations, the schema can also specify child resources.

This SOE includes 2 root level operations export and identify. It also includes 2 child resources: metadata and layers. The metadata resource is available at this URL:

http://<service-url>/exts/<extensionName>/metadata
Note that layers is a collection resource (indicated by the isCollection property being true). This implies the existence of multiple layer resources such that each layer resource is available at this URL:
http://<service-url>/exts/<extensionName>/layers/<layerId>
Also, each layer supports a query operation which is available at this URL:
http://<service-url>/exts/<extensionName>/layers/<layerId>/query
Each layer in turn includes a features child resource. Since features is also a collection resource, each feature resource is available at this URL:
http://<service-url>/exts/<extensionName>/layers/<layerId>/features/<featureId>

Schema 5 - POST-only Operations

{
  "operations" : [
    {
      "name" : "addStop", 
      "parameters" : ["location", "name"], 
      "supportedOutputFormats" : ["json"],
      "postOnly" : true
    }
  ]
}

Certain types of operations should only be allowed with HTTP POST. A method can be marked as such using the postOnly boolean flag. We'll discuss more on this later.

Resources

All SOEs will minimally support a root resource and optionally, child resources if the SOE schema (e.g. Schema 4) specifies them.

The REST handler always requests a JSON representation for resources from the SOE. If REST clients request a resource with f=json, the JSON as returned by the SOE is sent to the client. On the other hand, the Services Directory view of this resource consumes the JSON sent by the SOE and transforms it into HTML that can be shown on a web page.

Collection child resources

In Schema 4, layers is specified as a collection child resource of the root SOE resource. Let's assume that the JSON for the root resource returned by the SOE is as follows:

{
  "description: "Contitental US",
  "extent" : { "xmin" : ..., "ymin" : ..., ...},
  "spatialReference" : {...},
  ...
  
  "layers" : [
    { "id" : 0, "name" : "Cities", ... },
    { "id" : 1, "name" : "Counties", ... },
    { "id" : 2, "name" : "States", ... }
  ]
  
  ...
}

When displaying this as HTML in the Services Directory, the REST handler finds a layers property. Since the schema specifies this as a collection child resource, it first inspects if the value of this property is a JSON array. Further if each element in the array is a JSON object with an id and a name property, it displays a link using the name for display and the id in the URL. e.g. The Cities layer above gets the URL:

http://<service-url>/exts/<extensionName>/layers/0 //the Cities layer
In the Services Directory, the list of layers appears as shown below.

SOE method calls for resources

Accessing a SOE resource from the REST API actually incurs a call to the handleRESTRequest method on the IRESTRequestHandler interface of the SOE. For resource requests, the operationName parameter of this method will be an empty string (""). Whereas the resourceName parameter will be a string relative to the root SOE resource. Let's revisit Schema 4 and take a look at how requests for various REST resources translate into values of the resourceName parameter when calling handleRESTRequest

REST Resource URL resourceName parameter
http://<service-url>/exts/<extensionName> "" //empty string
http://<service-url>/exts/<extensionName>/metadata "metadata"
http://<service-url>/exts/<extensionName>/layers/1 "layers/1"
http://<service-url>/exts/<extensionName>/layers/1/features/37 "layers/1/features/37"

SOE developers are expected to be aware of this and return the resource representations based on the resourceName parameter.

Operations

If the SOE schema specifies that a certain resource supports operations, the Services Directory page for that resource will display links to those operations. For instance, Schema 2 and Schema 3 both specify that the root SOE resource supports buffer and near operations. Hence the Services Directory page for this resource will include links to these operations as shown below:

Operations without specified parameters

In Schema 2, only the name of operations is specified, i.e. there is no information pertaining to the parameters and output formats supported by that operation. In such cases, the Services Directory page for that operation presents a form where the user is required to provide both the parameter values as well as the parameter names. For instance, the Services Directory page for the buffer operation in Schema 2 will appear as shown below:

Operations with specified parameters

In Schema 3, both parameters and supported output formats for the buffer operation are specified. In such cases, the Services Directory page for that operation presents a form with parameter names as well as the list of supported formats populated as shown below:

SOE method calls for operations

Invoking an SOE operation from the REST API also incurs a call to the handleRESTRequest method on the IRESTRequestHandler interface of the SOE. For operation requests, the operationName parameter of this method will be a non-empty string. The resourceName parameter will continue to be a string relative to the root SOE resource. Let's revisit Schema 4 and take a look at how requests for various REST operations translate into values of the resourceName and operationName parameters when calling handleRESTRequest

REST Operation URL resourceName parameter operationName parameter
http://<service-url>/exts/<extensionName>/export "" //empty string "export"
http://<service-url>/exts/<extensionName>/layers/1/query "layers/1" "query"

SOE developers are expected to be aware of this and invoke the appropriate logic based on the combination of resourceName and operationName parameters.

Operation parameters

REST clients send operation parameters as query parameters either in the URL (for GETs) or in the body (for POSTs). Before making the handleRESTRequest call, the REST handler coerces the input parameters into a JSON object. The request parameter names become the JSON property names. The values are attempted to be coerced to valid JSON types - numbers, booleans, JSON objects, JSON arrays. If they cannot be coerced to any of the types mentioned above, they'll be treated as strings.

The outputFormat argument is set to the value of format parameter f.

As an example, consider this request for the near operation specified by Schema 3:

http://<service-url>/exts/<extensionName>/near?
location={x: -117.05, y: 34.11}&distance=2.5&&lookingFor=ATM&f=json

In this case, since the value of the location parameter is valid JSON it will be coerced to a JSON object. Similarly the value of distance will be coerced to a number and the value of lookingFor will be a string. Based on this, the operationInput parameter when making the handleRESTRequest call will be set to the following JSON formatted string:

{
  "location" : {x: -117.05, y: 34.11}, //JSON object
  "distance" : 2.5, //number
  "lookingFor" : "ATM" //string
}

Finally, the outputFormat parameter when making the handleRESTRequest call will be set to json (the value of the format parameter f).

POST-only operations

Operations that can permanently change the state of your system should not be allowed with HTTP GET. All add, update and delete operations fall in this category. SOE developers can mark such operations as POST-only operations using the postOnly property as show in Schema 5. The REST handler will enforce this condition by not calling the handleRESTRequest for POST-only operations if the request was made using anything but HTTP POST. An appropriate error message with an error code of 405 (Method not allowed) will be sent to the client in such cases.