Skip to content

Relationships API

amplifi edited this page Jun 29, 2017 · 1 revision

This document outlines the API design for organization project relationships that relate parties and spatial units with each other. Together, parties, spatial units, and relationships form the records, which are the primary data being stored by the Platform. For more background information, please refer to Platform data model.

The Platform currently stores three classes of relationships listed below. For v0.1 of the Platform, more complex relationships (like many-to-many) will not be supported.

Spatial : these are unidirectional spatial unit–to–spatial unit relationships that model things like Spatial Unit A is contained within Spatial Unit B.
On the backend, this class is represented by the SpatialRelationship model inside the spatial app.

Party : These are unidirectional party-to-party relationships that model things like Party A is a father of Party B.
On the backend, this class is represented by the PartyRelationship model inside the party app.

Tenure : these are unidirectional party–to–spatial unit relationships that model things like Party A owns Spatial Unit B.
On the backend, this class is represented by the TenureRelationship model inside the party app.

Overall API design

There are two types of API methods for relationships:

List : Methods that return a list of relationships

Single : Methods that manipulate (CRUD) a single relationship

Based on the expected use case, it does not make much sense to retrieve a list of all relationships of a project. (For statistics, a different endpoint will be provided in the future.) Relationships are always connected to the parties and spatial units that they are relating. Therefore, the relationship list API is always connected to a party or a spatial unit. The following are the list (HTTP GET) endpoints:

  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/spatial/{spatial-unit-id}/relationships/
  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/parties/{party-id}/relationships/

For the single-object APIs, the following are the create (HTTP POST) endpoints per relationship class:

  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/spatial/
  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/party/
  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/tenure/

And the following are the read (HTTP GET), update (HTTP PATCH), and delete (HTTP DELETE) endpoints per relationship class:

  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/spatial/{rel-id}/
  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/party/{rel-id}/
  • /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/tenure/{rel-id}

Cross-cutting concerns

Permissioning

It is intended that records of public projects would be visible. So for public projects, the list/read methods requests will not require any authorization tokens. In other circumstances (private projects, or create/update/delete methods), an authorization token is required in the request.

For example, the API request for listing all relationships for a specified party of a public project will look like the following:

GET /api/v1/organizations/{org-slug}/projects/{prj-slug}/parties/{party-id}/relationships/
Accept: application/json

For example, the API request for creating a new spatial relationship for a project will look like the following:

POST /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/spatial/
Accept: application/json
Content-type: application/json
Authorization: {token}

<<post-body>>

When the request requires an authorization token but none was provided or an invalid token was provided, the response will be an error:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
    "error": "<<error message>>"
}

Entity references

All relationships relate at least 2 other entities (parties or spatial units). For read operations, data for these entities are included in the returned data as a nested JSON object. For write operations, only the ID for the entity should be provided.

Example read data for a spatial relationship:

{
    "rel_class": "spatial",
    "id": "<<rel-id>>",
    "type": "C",
    "su1": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-1>>",
            "type": "MI",
            "name": "Community Park",
            "attributes": {}
        }
    },
    "su2": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-2>>",
            "type": "MI",
            "name": "Park Playground",
            "attributes": {}
        }
    },
    ...
}

Example write data for a spatial relationship:

{
    "id": "<<rel-id>>",
    "type": "C",
    "su1": "<<spatial-unit-id-1>>",
    "su2": "<<spatial-unit-id-2>>",
    ...
}

List API methods

List all relationships for a spatial unit

To get a list of all relationships for a particular spatial unit:

Request:

GET /api/v1/organizations/{org-slug}/projects/{prj-slug}/spatial/{spatial-unit-id}/relationships/
Accept: application/json

Response: The JSON format will be an array of objects each representing a relationship. The class of relationship that is represented by an object can be determined from the rel_class field which can either be "spatial" or "tenure".

HTTP/1.1 200 OK
Content-Type: application/json

[
    <<spatial-relationship-data-1>>,
    <<spatial-relationship-data-2>>,
    ...
    <<tenure-relationship-data-1>>,
    <<tenure-relationship-data-2>>,
    ...
}

List all relationships for a party

To get a list of all relationships for a particular party:

Request:

GET /api/v1/organizations/{org-slug}/projects/{prj-slug}/parties/{party-id}/relationships/
Accept: application/json

Response: The JSON format will be an array of objects each representing a relationship. The class of relationship that is represented by an object can be determined from the rel_class field which can either be "party" or "tenure".

HTTP/1.1 200 OK
Content-Type: application/json

[
    <<party-relationship-data-1>>,
    <<party-relationship-data-2>>,
    ...
    <<tenure-relationship-data-1>>,
    <<tenure-relationship-data-2>>,
    ...
}

List all relationships of a single class

For the previous two API methods, the class of relationships that will be returned can be limited to a single class by appending the URL query ?class=spatial, ?class=party, or ?class=tenure depending on the desired class.

The response will still be an array of objects but limited to the relationship class that was requested. If there are no relationships of the class, the array will be empty.

Using an unrecognized value for the class URL query parameter will result into an HTTP 400 Bad Request error.

Single API methods

Create a new relationship

Example API call for creating a new spatial relationship:

Request:

POST /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/spatial/
Content-Type: application/json
Accept: application/json
Authorization: {token}

{
    "type": "C",
    "su1": "<<spatial-unit-id-1>>",
    "su2": "<<spatial-unit-id-2>>"
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "rel_class": "spatial",
    "id": "<<rel-id>>",
    "type": "C",
    "su1": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-1>>",
            "type": "MI",
            "name": "Community Park",
            "attributes": {}
        }
    },
    "su2": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-2>>",
            "type": "MI",
            "name": "Park Playground",
            "attributes": {}
        }
    },
    "attributes": {}
}

Errors:

  • When the request contains an error, an HTTP 400 Bad Request error response is returned containing information about the error(s) detected. Some error causes are:
    • the organization or project specified in the URL is unknown
    • the JSON is malformed
    • the spatial unit IDs do not exist
    • the type field value is not recognized
  • When the user does not have permission to create a relationship in the project, an HTTP 403 Forbidden error response is returned.

Get a single relationship

Example API call for retrieving an existing spatial relationship:

Request:

GET /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/spatial/{rel-id}/
Accept: application/json

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "rel_class": "spatial",
    "id": "<<rel-id>>",
    "type": "C",
    "su1": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-1>>",
            "type": "MI",
            "name": "Community Park",
            "attributes": {}
        }
    },
    "su2": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-2>>",
            "type": "MI",
            "name": "Park Playground",
            "attributes": {}
        }
    },
    "attributes": {}
}

Errors:

  • When the request contains an error, an HTTP 400 Bad Request error response is returned containing information about the error(s) detected. Some error causes are:
    • the organization, project, or relationship specified in the URL is unknown
  • When the user does not have permission to retrieve the relationship in the project, an HTTP 403 Forbidden error response is returned.

Update a single relationship

Example API call for updating a new spatial relationship:

Request: Only the fields that need to be updated are required.

PATCH /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/spatial/{rel-id}/
Content-Type: application/json
Accept: application/json
Authorization: {token}

{
    "type": "S"
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "rel_class": "spatial",
    "id": "<<rel-id>>",
    "type": "S",
    "su1": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-1>>",
            "type": "MI",
            "name": "Community Park",
            "attributes": {}
        }
    },
    "su2": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                0.12345,
                3.45678
            ]
        },
        "properties": {
            "id": "<<spatial-unit-id-2>>",
            "type": "MI",
            "name": "Park Playground",
            "attributes": {}
        }
    },
    "attributes": {}
}

Errors:

  • When the request contains an error, an HTTP 400 Bad Request error response is returned containing information about the error(s) detected. Some error causes are:
    • the organization, project, or relationship specified in the URL is unknown
    • the JSON is malformed
    • the spatial unit IDs do not exist
    • the type field value is not recognized
  • When the user does not have permission to create a relationship in the project, an HTTP 403 Forbidden error response is returned.

Delete a single relationship

Request:

GET /api/v1/organizations/{org-slug}/projects/{prj-slug}/relationships/spatial/{rel-id}/
Accept: application/json
Authorization: {token}

Response:

HTTP/1.1 204 No Content

Errors:

  • When the request contains an error, an HTTP 400 Bad Request error response is returned containing information about the error(s) detected. Some error causes are:
    • the organization, project, or relationship specified in the URL is unknown
  • When the user does not have permission to retrieve the relationship in the project, an HTTP 403 Forbidden error response is returned.
Clone this wiki locally