FRAMES | NO FRAMES | Description | Schema | Resources | Operations |
URL | http://<service-url>/exts/<extensionName> |
---|---|
Parent Resource | Map Service |
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:
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
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>
query
operation which is available at this URL:
http://<service-url>/exts/<extensionName>/layers/<layerId>/query
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.
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
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.
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.