Skip to content

REST API: How to discover a resource's relations to other objects

bendiy edited this page Aug 19, 2013 · 36 revisions

Review the How to discover the schema of a resource documentation for an introduction on JSON-Schema.

Notice that the JSON-Schema for Contact has "$ref" references within it. There are four types of child relations references you can find within a JSON-Schema parent object.

toOne Nested Child Object:

...
        "address": {
          "title": "Address",
          "type": "object",
          "$ref": "AddressInfo"
        },
...

When you GET a Contact resource, it will have a property "address" that will have an "AddressInfo" object nested inside of it. To discover what the "address" property will contain, you should find the "AddressInfo" JSON-Schema. It will look similar to this:

...
    "AddressInfo": {
      "properties": {
        "number": {
          "title": "Number",
          "isKey": true,
          "required": true,
          "type": "string"
        },
        "isActive": {
          "title": "Is Active",
          "type": "boolean"
        },
        "line1": {
          "title": "Line1",
          "type": "string"
        },
        "line2": {
          "title": "Line2",
          "type": "string"
        },
        "line3": {
          "title": "Line3",
          "type": "string"
        },
        "city": {
          "title": "City",
          "type": "string"
        },
        "state": {
          "title": "State",
          "type": "string"
        },
        "postalCode": {
          "title": "Postal Code",
          "type": "string"
        },
        "country": {
          "title": "Country",
          "type": "string"
        }
      }
    },
...

Since this is a nested relation the object is contained within it's parent. However, it does refer to a different resource. Looking at the Discovery Document for Contact, you will find a resource called "AddressInfo" and it's associated methods. You can use this resource to determine how to edit a Contact's address.

toOne Object Key Relation:

...
      "salesRep": {
        "title": "Sales Rep",
        "type": "string",
        "$ref": "SalesRep/number"
      },
...

A toOne Object Key Relation is a single field that refers to the identification key of another object. You can identify this type of relation by looking for a forward slash "/" in the "$ref" property. This is a type of JSON-Path reference. It means that the field "salesRep" references the "SalesRep" object's "number" parameter. The difference between a toOne Object Key Relation and a toOne Nested Relation is the the full object is not nested in the parent, just it's key.

To add a new relation of this type you can discover it's resource type from the first part of the "$ref" path, "SalesRep", and what field to use for the relation from the second part of the "$ref" path, "number". You can list all of the "SalesRep" resources in a select list on a form. The user would then select which Sales Rep to associate the parent with and submit the form. If you need to make a relation to a new Sales Rep that does not exist yet, you must perform a POST on the "SalesRep" resource. You can then get the new Sale Rep's "number" and use that to PATCH your parent resource with the new relation.

toMany Nested Child Object:

...
        "comments": {
          "title": "Comments",
          "type": "array",
          "items": {
            "$ref": "ContactComment"
          }
        },
...

The toMany Nested Child objects act very similar to the toOne Nested Child objects, but are represented as an array of objects under the property. For example, a Contact resource's "comments" property might look like this:

...
  "comments": [
    {
      "uuid": "230f6470-3326-491e-b897-9a362e45ac48",
      "commentType": "General",
      "text": "test general comment",
      "created": "2013-07-12T23:13:58.505Z",
      "createdBy": "admin"
    },
    {
      "uuid": "649c83c6-a710-4b0a-9660-32a1f87ca80e",
      "commentType": "General",
      "text": "second comment",
      "created": "2013-07-12T23:14:17.079Z",
      "createdBy": "admin"
    }
  ],
...

One major difference between toOne Nested Child objects and toMany Nested Child objects is that the toMany Nested JSON-Schema "$ref" reference does not have a related resource that matches it. There is no "ContactComment" resource with a "list" method. You will only find that reference in the JSON-Schema. In this case, when you want to add or edit a "comment" under a "Contact" resource, you do it directly on the parent and then call the "Contact" "patch" method to save it. The JSON-Schema reference is there for you to know what that object should look like when you create it, to build edit forms and validate their data types.

toMany Object Key Relation:

...
        "incidentRelations": {
          "title": "Incident Relations",
          "type": "array",
          "items": {
            "$ref": "IncidentRelation/number"
          }
        },
...

toMany Object Key Relations relate one type of resource instance to another type of resource instance with an identification key. The parent object contains an array of child object's identification keys. There is no nesting involved. In most cases, the child is a full resource on the REST API and you can use it's "list" method to find other instances of the child resource to associate with a parent.

You can identify this type of relation by looking for a forward slash "/" in the "items" -> "$ref" property. This is a type of JSON-Path reference. It means that the field "incidentRelations" is an array of references to "IncidentRelation" objects using their "number" parameter.

To add a new relation of this type you can discover it's resource type from the first part of the "$ref" path, "IncidentRelation", and what field to use for the relation from the second part of the "$ref" path, "number".

However, if you want to create a relation to a new resource that does not exist yet, you would then use the "Incident" resource's "insert" method to add a new "Incident" first. Once the Incident was saved you could then add a relation to the new "Incident" under a "Contact" "incidentRelations" property array. You cannot perform actions from a "Contact" resource that affect an "Incident" resource. If you need to change the "Incident" referenced in a "Contact" "incidentRelations" property, you should make those changes to the "Incident" resource itself. toMany Object Relations are simply a way to link different types of resource objects together.

The following is an example of a "Contact" "incidentRelations" property. This is showing that the Contact is related to Incidents, "15002" and "15005".

...
    "incidentRelations": [
      "15002",
      "15005"
    ],
...

You can use these relations to add hyperlinks from a Contact resource directly to the referenced Incidents to make it easy for a user to navigate from one resource to the referenced resources.

If you want to provide your end users with more information about the relations, you could use the "IncidentRelation" "get" method to return more detailed information. The "...Relation" resources are similar to the "...ListItem" resources in that they provide a limited set of fields for a main parent resource. Those fields are generally enough information that the end user will know what the resource instance is. This makes "...Relation" and "...ListItem" resources ideal for displaying in a list and/or table and then linking to the main resource to view the details or perform other CRUD actions.