AddToDefinition not working in Portal

906
4
Jump to solution
04-24-2023 10:28 AM
LNX
by
New Contributor II

I'm trying to create a new hosted feature layer in Portal (ArcGIS Enterprise 10.9) by making a series of calls to the REST API.

What I've tried:

1. POST to https://{mydomain}/portal/generateToken

This is working.  I send valid credentials and get a token in return.  I use the received token in the following requests.

 

2. POST to https://{mydomain}/portal/sharing/rest/content/users/{username}/createService?token={token}

This is working.  I see the new empty service in the user's content in Portal.

The createService parameter contains the following JSON

{
    "name": "Test11",
    "serviceDescription": "this is a test",
    "hasStaticData": false,
    "maxRecordCount": 10000,
    "supportedQueryFormats": "JSON",
    "capabilities": "Create,Delete,Query,Update,Editing",
    "description": "this is a test",
    "copyrightText": null,
    "spatialReference": {
        "wkid": 102100
    },
    "initialExtent": null,
    "allowedGeometryUpdate": true,
    "units": "esriMeters",
    "xssPreventionInfo": {
        "xssPreventionEnabled": true,
        "xssPreventionRule": "input",
        "xssInputRule": "rejectInvalid"
    }
}

 

After visiting the new service's Overview page in Portal, I use it's URL to build the next request....

 

3. POST to https://{mydomain}/server/rest/services/Hosted/Test11/FeatureServer/addToDefinition?f=json&token={to...

I add a url encoded key/value pair to the above request body named "addToDefinition" as described in this documentation.

{
    "layers": [
        {
            "id": 0,
            "name": "TestLayer01",
            "type": "Feature Layer",
            "defaultVisibility": true,
            "supportedQueryFormats": "JSON", 
            "capabilities": "Create,Delete,Query,Update,Editing,Extract,Sync", 
            "fields": [
                {
                    "name": "FID", 
                    "type": "esriFieldTypeInteger", 
                    "actualType": "int", 
                    "alias": "FID", 
                    "sqlType": "sqlTypeInteger", 
                    "length": 4, 
                    "nullable": false, 
                    "editable": false, 
                    "domain": null, 
                    "defaultValue": null
                },
                {
                    "name": "CATEGORY", 
                    "type": "esriFieldTypeString", 
                    "actualType": "nvarchar", 
                    "alias": "CATEGORY", 
                    "sqlType": "sqlTypeNVarchar", 
                    "length": 40, 
                    "nullable": true, 
                    "editable": true, 
                    "domain": null, 
                    "defaultValue": null
                }
            ]
        }
    ]
}

This is not working. Although I get a 200 response, the response body simply contains the empty service's info.  No new feature layer has been added to the empty service in portal.

 

Do I have the request URL wrong, or do I need to include some additional properties in the JSON structure?

0 Kudos
1 Solution

Accepted Solutions
LNX
by
New Contributor II

I found the problem(s).  Unfortunately the documentation does not specify which of the ump-teen properties of "addToDefinition" are required.  I've been able to figure them out by trial and error.  If anyone else runs into this, here's how I fixed it.

1. First, the request URL was indeed wrong.  It needs to be https://{mydomain}/server/rest/admin/services/Hosted/Test11/FeatureServer/addToDefinition?f=json&token={token}

2. After fixing the URL and resending, I got this error:

 

{
    "error": {
        "code": 500,
        "message": "\"objectIdField\" attribute was not passed in the service definition and SDS did not discover a suitable field.",
        "details": []
    }
}

 

The above error indicated that my request JSON addToDefinition object was missing the "objectIdField" property which specifies which of the fields is the objectID.  Updating the original request JSON to include the missing property resolves this error.

 

{
    "layers": [
        {
            "id": 0,
            "name": "TestLayer01",
            "type": "Feature Layer",
            "defaultVisibility": true,
            "supportedQueryFormats": "JSON", 
            "capabilities": "Create,Delete,Query,Update,Editing,Extract,Sync", 
            "objectIdField": "FID",
            "fields": [
                {
                    "name": "FID", 
                    "type": "esriFieldTypeInteger", 
                    "actualType": "int", 
                    "alias": "FID", 
                    "sqlType": "sqlTypeInteger", 
                    "length": 4, 
                    "nullable": false, 
                    "editable": false, 
                    "domain": null, 
                    "defaultValue": null
                },
                {
                    "name": "CATEGORY", 
                    "type": "esriFieldTypeString", 
                    "actualType": "nvarchar", 
                    "alias": "CATEGORY", 
                    "sqlType": "sqlTypeNVarchar", 
                    "length": 40, 
                    "nullable": true, 
                    "editable": true, 
                    "domain": null, 
                    "defaultValue": null
                }
            ]
        }
    ]
}

 

3. Next it complained about the "type" property assigned to the object ID field (which in this case is FID). 

 

{
    "error": {
        "code": 500,
        "message": "Wrong type of the ObjectID field.",
        "details": []
    }
}

 

ESRI has a typo in their documentation examples.  I needed to change the FID field definition from this...

"type": "esriFieldTypeInteger"

to this...

"type": "esriFieldTypeOID"

4. Next it complained about the missing geometryType property.

 

{
    "error": {
        "code": 500,
        "message": "JSONObject[\"geometryType\"] not found.",
        "details": []
    }
}

 

 So I added "geometryType": "esriGeometryPoint" to the layer definition and kept going.

5. Now it's mad that I didn't specify and extent....

 

{
    "error": {
        "code": 500,
        "message": "JSONObject[\"extent\"] not found.",
        "details": []
    }
}

 

This one is particularly annoying because I don't necessarily know what my extent will be yet, but since it's a required property I borrowed the extent object from the example in the docs.  Moving on...

6. And lastly, it requires the "hasAttachments" property.  I set mine to false and resubmitted.  Finally some joy.

 

{
    "success": true,
    "layers": [
        {
            "name": "TestLayer01",
            "id": 0
        }
    ]
}

 

 

The final request JSON that succeeded is below.  I think this may be the absolute minimum that's required, although there are many more properties that can be added.

{
    "layers": [
        {
            "id": 0,
            "name": "TestLayer01",
            "type": "Feature Layer",
            "defaultVisibility": true,
            "supportedQueryFormats": "JSON",
            "capabilities": "Create,Delete,Query,Update,Editing,Extract,Sync",
            "geometryType": "esriGeometryPoint",
            "hasAttachments": false,
            "extent": {
                "xmin": -13090714.767112788,
                "ymin": 3841739.0914657288,
                "xmax": -12922032.654624918,
                "ymax": 3962581.2727843975,
                "spatialReference": {
                    "wkid": 102100,
                    "latestWkid": 3857
                }
            },
            "objectIdField": "FID",
            "fields": [
                {
                    "name": "FID",
                    "type": "esriFieldTypeOID",
                    "actualType": "int",
                    "alias": "FID",
                    "sqlType": "sqlTypeInteger",
                    "length": 4,
                    "nullable": false,
                    "editable": false,
                    "domain": null,
                    "defaultValue": null
                },
                {
                    "name": "CATEGORY",
                    "type": "esriFieldTypeString",
                    "actualType": "nvarchar",
                    "alias": "CATEGORY",
                    "sqlType": "sqlTypeNVarchar",
                    "length": 40,
                    "nullable": true,
                    "editable": true,
                    "domain": null,
                    "defaultValue": null
                }
            ]
        }
    ]
}

View solution in original post

4 Replies
LNX
by
New Contributor II

I found the problem(s).  Unfortunately the documentation does not specify which of the ump-teen properties of "addToDefinition" are required.  I've been able to figure them out by trial and error.  If anyone else runs into this, here's how I fixed it.

1. First, the request URL was indeed wrong.  It needs to be https://{mydomain}/server/rest/admin/services/Hosted/Test11/FeatureServer/addToDefinition?f=json&token={token}

2. After fixing the URL and resending, I got this error:

 

{
    "error": {
        "code": 500,
        "message": "\"objectIdField\" attribute was not passed in the service definition and SDS did not discover a suitable field.",
        "details": []
    }
}

 

The above error indicated that my request JSON addToDefinition object was missing the "objectIdField" property which specifies which of the fields is the objectID.  Updating the original request JSON to include the missing property resolves this error.

 

{
    "layers": [
        {
            "id": 0,
            "name": "TestLayer01",
            "type": "Feature Layer",
            "defaultVisibility": true,
            "supportedQueryFormats": "JSON", 
            "capabilities": "Create,Delete,Query,Update,Editing,Extract,Sync", 
            "objectIdField": "FID",
            "fields": [
                {
                    "name": "FID", 
                    "type": "esriFieldTypeInteger", 
                    "actualType": "int", 
                    "alias": "FID", 
                    "sqlType": "sqlTypeInteger", 
                    "length": 4, 
                    "nullable": false, 
                    "editable": false, 
                    "domain": null, 
                    "defaultValue": null
                },
                {
                    "name": "CATEGORY", 
                    "type": "esriFieldTypeString", 
                    "actualType": "nvarchar", 
                    "alias": "CATEGORY", 
                    "sqlType": "sqlTypeNVarchar", 
                    "length": 40, 
                    "nullable": true, 
                    "editable": true, 
                    "domain": null, 
                    "defaultValue": null
                }
            ]
        }
    ]
}

 

3. Next it complained about the "type" property assigned to the object ID field (which in this case is FID). 

 

{
    "error": {
        "code": 500,
        "message": "Wrong type of the ObjectID field.",
        "details": []
    }
}

 

ESRI has a typo in their documentation examples.  I needed to change the FID field definition from this...

"type": "esriFieldTypeInteger"

to this...

"type": "esriFieldTypeOID"

4. Next it complained about the missing geometryType property.

 

{
    "error": {
        "code": 500,
        "message": "JSONObject[\"geometryType\"] not found.",
        "details": []
    }
}

 

 So I added "geometryType": "esriGeometryPoint" to the layer definition and kept going.

5. Now it's mad that I didn't specify and extent....

 

{
    "error": {
        "code": 500,
        "message": "JSONObject[\"extent\"] not found.",
        "details": []
    }
}

 

This one is particularly annoying because I don't necessarily know what my extent will be yet, but since it's a required property I borrowed the extent object from the example in the docs.  Moving on...

6. And lastly, it requires the "hasAttachments" property.  I set mine to false and resubmitted.  Finally some joy.

 

{
    "success": true,
    "layers": [
        {
            "name": "TestLayer01",
            "id": 0
        }
    ]
}

 

 

The final request JSON that succeeded is below.  I think this may be the absolute minimum that's required, although there are many more properties that can be added.

{
    "layers": [
        {
            "id": 0,
            "name": "TestLayer01",
            "type": "Feature Layer",
            "defaultVisibility": true,
            "supportedQueryFormats": "JSON",
            "capabilities": "Create,Delete,Query,Update,Editing,Extract,Sync",
            "geometryType": "esriGeometryPoint",
            "hasAttachments": false,
            "extent": {
                "xmin": -13090714.767112788,
                "ymin": 3841739.0914657288,
                "xmax": -12922032.654624918,
                "ymax": 3962581.2727843975,
                "spatialReference": {
                    "wkid": 102100,
                    "latestWkid": 3857
                }
            },
            "objectIdField": "FID",
            "fields": [
                {
                    "name": "FID",
                    "type": "esriFieldTypeOID",
                    "actualType": "int",
                    "alias": "FID",
                    "sqlType": "sqlTypeInteger",
                    "length": 4,
                    "nullable": false,
                    "editable": false,
                    "domain": null,
                    "defaultValue": null
                },
                {
                    "name": "CATEGORY",
                    "type": "esriFieldTypeString",
                    "actualType": "nvarchar",
                    "alias": "CATEGORY",
                    "sqlType": "sqlTypeNVarchar",
                    "length": 40,
                    "nullable": true,
                    "editable": true,
                    "domain": null,
                    "defaultValue": null
                }
            ]
        }
    ]
}
LorenzoPeve
New Contributor

@LNX not sure if you will see this message but you saved my day! I was struggling with the same and this works!

0 Kudos
ChrisBeaudette
Occasional Contributor

I'm having a similar but slightly different experience trying to add an index to a hosted feature layer in ArcGIS Enterprise v11.1.  I've walked through the trial-and-error exercise of:

  1. Get the original feature layer definition from https://<MY-HOSTING-SERVER-HOSTNAME>/<WEB-ADAPTOR-NAME>/rest/admin/services/Hosetd/<SERVICE-NAME>/Fe...
  2. Modify it to:
    • remove existing indexes 
    • add the indexes I want to add
  3. Attempt to make the change with https://<MY-HOSTING-SERVER-HOSTNAME>/<WEB-ADAPTOR-NAME>/rest/admin/services/Hosetd/<SERVICE-NAME>/Fe.../addToDefinition

From here I went through several iterations of "Field <FIELD-NAME> cannot be updated".  I stripped out everything except "fields": [] and "indexes": [] (leaving out the existing indexes) and got past the "Field <FIELD-NAME> cannot be updated" errors, but am now getting the error:  

ERROR: "<SERVICE-NAME>_evw" is not a table or materialized view

The '<SERVICE-NAME>_evw' appears in the original layer definition in the adminLayerInfo.viewName object, but adminLayerInfo was stripped out of the JSON posted to addToDefinition in order to get past the "Field <FIELD-NAME> cannot be updated" errors.  

At the end of the day I just want to add indexes to this layer.  

 

0 Kudos
ChrisBeaudette
Occasional Contributor

I found some additional info as well that might help, in particular the reason behind the ERROR: "<SERVICE-NAME>_evw" is not a table or materialized view. My feature service had 4 views created from it, all of which had editing and sync enabled. To get past the error we had to turn sync off for all views and the feature service itself. Once done we were able to add indexes.

CAUTION:  When disabling sync for FS + views the feature service got into an unstable state where the data was not rendering in the Data tab of the FS until we bounced the data store.  (Oddly the data showed up for the views that were created from the parent feature service, but not the feature service itself).  We ended up having to rebuild the feature service from scratch.  So as always, MAKE A BACKUP BEFORE YOU START! 🙂 

0 Kudos