This topic discusses the custom data provider specification.
Registration Object
Every custom data provider has a file named index.js that exports a registration object containing provider information. The object describes how to load and use the provider. The following is the code that is automatically included in the index.js file by the Custom Data Feeds (CDF) command line tool.
const packageInfo = require('../package.json');
const csconfigInfo = require('../cdconfig.json');
const provider = {
type: csconfigInfo.type,
name: csconfigInfo.name,
version: packageInfo.version,
hosts: csconfigInfo.properties.hosts,
disableIdParam: csconfigInfo.properties.disableIdParam,
Model: require('./model')
};
module.exports = provider;
The table below describes each field in detail:
Field | Required? | Type | Description |
---|---|---|---|
type | Yes | string | Set to 'provider' |
name | Yes | string | URL-safe provider name |
version | Yes | string | Provider version number |
hosts | No | Boolean | Add a :host parameter to routes |
disable | No | Boolean | Remove the :id parameter from routes |
Model | Yes | class | require statement for Model class |
routes | No | Object[] | Array of provider-specific route objects |
Controller | No | class | Controller class that supports route handling |
The auto-generated code pulls the provider version from the package.json file and other fields from the cdconfig.json file. To modify these fields, change the corresponding values in the cdconfig.json file instead of the index.js file.
Model Class
Every custom data provider implements a Model
class, which is usually
in the model.js file. The Model class includes a get
function
that will contain code for fetching and tranforming remote data into GeoJSON.
The following table describes the arguments that the get
function accepts.
Name | Type | Description |
---|---|---|
req | Object | Express.js request object |
callback | Function | Callback function that either returns a GeoJSON object or an error |
Request Object
The following code snippet illustrates how to retrieve the host
and
id
URL parameters from the request object:
const host = req.params.host;
const id = req.params.id;
The host
parameter will only appear if the value of the host field in
the cdconfig.json file is set to true
. Similarly, the id
parameter will only appear if the value of the disable
field in
the cdconfig.json file is set to false
. You can use these
parameters to build the URL to the remote data source.
Callback Function
Pass the constructed GeoJSON to the callback function inside the get
function as follows.
callback(null,geojson)
;
If an error occurs, invoke the callback function with the error as follows:
callback(err);
GeoJSON Metadata
Custom Data Feeds requires that the GeoJSON be decorated with a property called metadata
.
It should have an object as its value. This object contains information important for
translating the GeoJSON to its feature service equivalent. The table below describes
some of the key metadata properties:
Field | Type | Description | Example |
---|---|---|---|
capabilities | string | Identifies the various capabilities of an ArcGIS Feature Service. Individual capbabliites are listed in a comma-delimited string. | Create,Delete,Query,Update,Editing |
default | Boolean | Specifies the default visibility of the layer. | true |
description | string | Description of the layer. | My amazing dataset |
display | string | The name of the layer's primary display field. | FLD0_ |
fields | object[] | An arrary of objects that define feature attributes. If you decide to define one attribute, then you must define all of your attributes. | [{ name: |
geometry | string | Geometry type of features. If not set, it is inferred from first feature in the dataset. If set to null , it will assume tabular data. Possible values include: Point , Multi , Line , Multi , Polygon , Multi , and null . | Point |
has | Boolean | Identifies if the feature should support attachments. | false |
has | Boolean | false | |
has | Boolean | Indicates whether the features have elevation (z) values. | false |
id | string | The unique ID assigned to the layer. | 1 |
i | string | Every feature layer must have a field that uniquely identifies each feature. This property will be used as the feature's OBJECTID . | id |
max | number | Maximum number of features the provider can return at once. | 2000 |
max | number | Defines the maximum scale (most zoomed in) at which the layer is visible in the view. | 99000 |
min | number | Defines the minimum scale (most zoomed out) at which the layer is visible in the view. | 1000 |
name | string | Each feature layer must have a name that differentiates it from all other layers. This is the name of this particular layer. | Test Layer |
relationships | object[] | An array of relationship objects for the layer. | SAMPLE |
renderer | object | Defines how to visually represent each feature. | SAMPLE |
supports | Boolean | Indicates whether the query response supports pagination. | true |
templates | Feature | An array of feature templates | [{"name": "<template |
time | object | Used to store information such as start and end time for a feature. | SAMPLE |
If your data does not contain a field that can be used as the OBJECTID
, you can leave i
undefined.
In such cases Custom Data Feeds will create an OBJECTID
for each feature by default. However, this is
less than ideal as it impacts performance and in very rare cases may lead to OBJECTID
collisions. The
best practice is to have a field on the raw data that meets the requirements of i
.
Routes and Controllers
Routes
To use provider-specific routes, ensure that the routes
field in the
index.js file points to a file that exports an array of route
definition objects. The following table describes the fields that each
route definition object must contain.
Field | Type | Description |
---|---|---|
path | string | Express.js-style route that includes optional parameters |
methods | string[] | HTTP methods that this route can handle |
handler | string | Name of the controller function that should handle requests at this route |
Controllers
Set the handler
field of each route definition object to the function
name that handles requests for that route. You can define these
functions in a Controller
class. The Controller
field in the
index.js file must reference the Controller
class. Below is an
example of how to implement a Controller
class.
function Controller (model) {
this.model = model;
}
Controller.prototype.test = function (req, res) {
res.status(200).json({version: '1.0.0'});
};