Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 29 Next »

GraphQL Occupancy API offers similar functionality to REST Occupancy API, however, there are additional benefits to using GraphQL.

You can select the fields you want to receive from the API. By requesting only the required fields from the API you can decrease traffic and consequently increase load speed.

Additionally, GraphQL Occupancy API supports subscriptions, which allows you to receive real-time occupancy updates.

Authorization

In order to authorize with this API, you need to add the following header to your request:

Key

Value

Authorization

<your token>

Your token can be obtained from the Company Info section of the Nwave’s console.

Object & Field Descriptions

  • PositionOccupancy - describes a position and its occupancy state

    • id - position id

    • customId - user-defined id

    • groupId - position’s group id

    • occupancyStatus - parking space occupancy status

    • statusChangeTime - latest occupancy status change time

    • location - object containing latitude and longitude coordinates

  • GroupOccupancy - describes a group, its positions and their occupancy states

    • id - group id

    • name - group user-defined name

    • customId - group user-defined id

    • location - object containing latitude and longitude coordinates

    • positionsOccupancy - list of all positions inside a group with its occupancy information

    • summary - group occupancy summary (total positions number, number of occupied and free positions)

The summary object should be used to display availability for all parking group types

  • SubscriptionArea - special object for describing occupancy states changes for some area

    • id - area id

    • location - object containing latitude and longitude coordinates

    • radius - area’s radius in meters

    • granularity - user-defined type for returned objects. Available values: [Position, Level, Group, Zone]

    • updates - list of Occupancy objects. Type of objects depends on the selected granularity option.

    • updateTime - the time of last occupancy status update

Documentation

The following GraphQL schema describes data types and operations that can be performed.

schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}

enum OccupancyStatus {
    Occupied
    Free
}

enum SubscriptionGranularity {
    Position
    Level
    Group
    Zone
}

type Location @aws_api_key @aws_lambda {
    lat: Float!
    lon: Float!
}

input LocationInput {
    lat: Float!
    lon: Float!
}

type OccupancySummary  @aws_api_key @aws_lambda {
    total: Int!
    occupied: Int!
    available: Int!
    undefined: Int!
}

input OccupancySummaryInput {
    total: Int!
    occupied: Int!
    available: Int!
    undefined: Int!
}

type PositionOccupancy  @aws_api_key @aws_lambda {
    id: Int!
    customId: String
    groupId: Int
    occupancyStatus: OccupancyStatus
    statusChangeTime: AWSDateTime
    location: Location!
}

input PositionOccupancyInput {
    id: Int!
    customId: String
    groupId: Int!
    occupancyStatus: OccupancyStatus!
    statusChangeTime: AWSDateTime!
    location: LocationInput!
}

type GroupOccupancy  @aws_api_key @aws_lambda {
    id: Int!
    zoneId: Int
    levelId: Int
    name: String!
    groupType: String!
    customId: String
    location: Location
    positionsOccupancy: [PositionOccupancy]
    summary: OccupancySummary
}

input GroupOccupancyInput {
    id: Int!
    zoneId: Int
    levelId: Int
    name: String!
    groupType: String!
    customId: String
    location: LocationInput!
    positionsOccupancy: [PositionOccupancyInput!]!
    summary: OccupancySummaryInput!
}

type LevelOccupancy  @aws_api_key @aws_lambda {
    id: Int
    name: String
    zoneId: Int!
    floorNumber: Int
    summary: OccupancySummary
}

input LevelOccupancyInput {
    id: Int
    zoneId: Int!
    floorNumber: Int
    name: String
    summary: OccupancySummaryInput!
}

type ZoneOccupancy  @aws_api_key @aws_lambda {
    id: Int!
    name: String!
    projectId: String
    summary: OccupancySummary
}

input ZoneOccupancyInput {
    id: Int!
    name: String!
    projectId: Int
    summary: OccupancySummaryInput!
}

union RtaUpdateObject = ZoneOccupancy | LevelOccupancy | GroupOccupancy | PositionOccupancy

interface SubscriptionArea {
    id: Int!
    location: Location
    radius: Int
    zoneId: [Int]
    levelId: [Int]
    floorNumber: [Int]
    groupId: [Int]
    labels: [String]
    granularity: SubscriptionGranularity!
    expiresOn: AWSDateTime!
}

type SubscriptionAreaNoUpdates implements SubscriptionArea @aws_api_key @aws_lambda {
    id: Int!
    location: Location
    radius: Int
    zoneId: [Int]
    levelId: [Int]
    floorNumber: [Int]
    groupId: [Int]
    labels: [String]
    granularity: SubscriptionGranularity!
    expiresOn: AWSDateTime!
}

type SubscriptionAreaWithUpdates implements SubscriptionArea @aws_api_key @aws_lambda {
    id: Int!
    location: Location
    radius: Int
    zoneId: [Int]
    levelId: [Int]
    floorNumber: [Int]
    groupId: [Int]
    labels: [String]
    granularity: SubscriptionGranularity!
    expiresOn: AWSDateTime!
    updates: [RtaUpdateObject]
    updateTime: AWSDateTime
}

type Query {
    groupOccupancy(id: Int!): GroupOccupancy @aws_api_key @aws_lambda
    findGroupOccupancies(
        ids: [Int]
        lat: Float
        lon: Float
        radius: Int
        levelId: [Int!]
        floorNumber: [Int!]
        zoneId: [Int!]
        projectId: Int
        groupCustomId: String
        limit: Int = 50
        offset: Int
    ) : [GroupOccupancy] @aws_api_key @aws_lambda
    findPositionOccupancies(
        ids: [Int]
        lat: Float
        lon: Float
        radius: Int
        groupId: [Int!]
        levelId: [Int!]
        floorNumber: [Int!]
        zoneId: [Int!]
        projectId: Int
        groupCustomId: String
        limit: Int = 50
        offset: Int
    ) : [PositionOccupancy] @aws_api_key @aws_lambda
}

type Mutation {
    createSubscriptionArea(
        lat: Float,
        lon: Float,
        radius: Int,
        zoneId: [Int],
        levelId: [Int],
        floorNumber: [Int],
        groupId: [Int],
        labels: [String],
        granularity: SubscriptionGranularity
    ): SubscriptionAreaNoUpdates @aws_api_key @aws_lambda
    updateSubscriptionArea(
        id: Int!,
        lat: Float,
        lon: Float,
        radius: Int,
        zoneId: [Int],
        levelId: [Int],
        floorNumber: [Int],
        groupId: [Int],
        labels: [String],
        granularity: SubscriptionGranularity
    ): SubscriptionAreaNoUpdates @aws_api_key @aws_lambda
    updatePositionOccupancy(
        positionId: Int!,
        occupancyStatus: OccupancyStatus!,
        timestamp: String!
    ): PositionOccupancy @aws_api_key
    pushPositionUpdates(
        id: Int!,
        location: LocationInput,
        radius: Int,
        zoneId: [Int],
        levelId: [Int],
        floorNumber: [Int],
        groupId: [Int],
        labels: [String],
        granularity: SubscriptionGranularity!,
        expiresOn: AWSDateTime!,
        updates: [PositionOccupancyInput!]!,
        updateTime: String!
    ): SubscriptionAreaWithUpdates @aws_api_key
    pushGroupUpdates(
        id: Int!,
        location: LocationInput,
        radius: Int,
        zoneId: [Int],
        levelId: [Int],
        floorNumber: [Int],
        groupId: [Int],
        labels: [String],
        granularity: SubscriptionGranularity!,
        expiresOn: AWSDateTime!,
        updates: [GroupOccupancyInput!]!,
        updateTime: String!
    ): SubscriptionAreaWithUpdates @aws_api_key
    pushLevelUpdates(
        id: Int!,
        location: LocationInput,
        radius: Int,
        zoneId: [Int],
        levelId: [Int],
        floorNumber: [Int],
        groupId: [Int],
        labels: [String],
        granularity: SubscriptionGranularity!,
        expiresOn: AWSDateTime!,
        updates: [LevelOccupancyInput!]!,
        updateTime: String!
    ): SubscriptionAreaWithUpdates @aws_api_key
    pushZoneUpdates(
        id: Int!,
        location: LocationInput,
        radius: Int,
        zoneId: [Int],
        levelId: [Int],
        floorNumber: [Int],
        groupId: [Int],
        labels: [String],
        granularity: SubscriptionGranularity!,
        expiresOn: AWSDateTime!,
        updates: [ZoneOccupancyInput!]!,
        updateTime: String!
    ): SubscriptionAreaWithUpdates @aws_api_key
}

type Subscription {
    onSubscriptionAreaUpdates(id: Int!): SubscriptionAreaWithUpdates @aws_api_key @aws_lambda @aws_subscribe(mutations : ["pushPositionUpdates", "pushGroupUpdates", "pushLevelUpdates", "pushZoneUpdates"])
}

Operations

The following operations can be performed using either Postman or curl command except for subscription operations.

groupOccupancy

This query will return the occupancy of a single group.

Query

query MyQuery {
  groupOccupancy(id: 123) {
    id
    customId
    name
    location {
      lat
      lon
    }
    positionsOccupancy {
      customId
      id
      groupId
      location {
        lat
        lon
      }
      occupancyStatus
      statusChangeTime
    }
  }
}

Response

{
  "data": {
    "groupOccupancy": {
      "id": 3544,
      "customId": null,
      "name": "Foo",
      "location": {
        "lat": 51.493601937687224,
        "lon": -0.12852029611716095
      },
      "positionsOccupancy": [
        {
          "customId": "",
          "id": 1,
          "groupId": 123,
          "location": {
            "lat": 51.49360068522545,
            "lon": -0.1286061268139623
          },
          "occupancyStatus": "Free",
          "statusChangeTime": "2021-01-27T19:22:47.548+00:00"
        },
        {
          "customId": "",
          "id": 2,
          "groupId": 123,
          "location": {
            "lat": 51.493601937687224,
            "lon": -0.12852029611716098
          },
          "occupancyStatus": "Occupoed",
          "statusChangeTime": "2021-01-27T18:56:53.502+00:00"
        }
      ]
    }
  }
}

findGroupOccupancies

This query will return a list of group occupancies.

Query

query MyQuery {
  findGroupOccupancies(ids: [1234]) {
    id
    location {
      lat
      lon
    }
    summary {
      available
      occupied
      total
      undefined
    }
  }
}

 

Response

{
  "data": {
    "findGroupOccupancies": [
      {
        "id": 1234,
        "location": {
          "lat": 50.780416909504915,
          "lon": -1.0914407438684124
        },
        "summary": {
          "available": 34,
          "occupied": 13,
          "total": 47,
          "undefined": 0
        }
      }
    ]
  }
}

findPositionOccupancies

This query will return a list of position occupancies.

Query

query MyQuery {
  findPositionOccupancies(ids: [1]) {
    id
    location {
      lat
      lon
    }
    occupancyStatus
    statusChangeTime
    groupId
    customId
  }
}

 

Response

{
  "data": {
    "findPositionOccupancies": [
      {
        "id": 12345,
        "location": {
          "lat": 51.49360068522545,
          "lon": -0.1286061268139623
        },
        "occupancyStatus": "Free",
        "statusChangeTime": "2021-01-27T19:22:47.548+00:00",
        "groupId": 123,
        "customId": ""
      }
    ]
  }
}

createSubscriptionArea

This mutation will create a new subscription area.

Subscription Area Expiration

By default, subscription areas expire 5 minutes after creation. Once a subscription area is expired, it cannot be extended and subscribers will stop receiving updates.

Mutation

mutation MyMutation {
  createSubscriptionArea(
    granularity: Group, 
    lat: 51.493930, 
    lon: -0.129030, 
    radius: 100
  ) {
    expiresOn
    granularity
    id
    location {
      lat
      lon
    }
    radius
  }
}

 

Response

{
  "data": {
    "createSubscriptionArea": {
      "expiresOn": "2021-01-28T23:20:06.232+00:00",
      "granularity": "Group",
      "id": 1,
      "location": {
        "lat": 51.49393,
        "lon": -0.12903
      },
      "radius": 100
    }
  }
}

onSubscriptionAreaUpdates

This subscription will subscribe to occupancy updates inside an area.

Selected updates object type must correspond to the granularity of the created search area:

  1. granularity: Position → updates { … on PositionOccupancy }

  2. granularity: Group → updates { … on GroupOccupancy }

If you are unsure of the granularity for your subscription area, you can specify both types inside the updates.

Subscription

subscription MySubscription {
  onSubscriptionAreaUpdates(id: 1) {
    id
    expiresOn
    granularity
    location {
      lat
      lon
    }
    radius
    updateTime
    updates {
      ... on GroupOccupancy {
        id
        name
        customId
        location {
          lat
          lon
        }
        positionsOccupancy {
          customId
          groupId
          id
          location {
            lat
            lon
          }
          occupancyStatus
          statusChangeTime
        }
        summary {
          undefined
          total
          occupied
          available
        }
      }
    }
  }
}

 

Update

{
  "data": {
    "onSubscriptionAreaUpdates": {
      "id": 1,
      "expiresOn": "2021-01-28T23:20:06.232+00:00",
      "granularity": "Group",
      "location": {
        "lat": 51.49393,
        "lon": -0.12903
      },
      "radius": 1000,
      "updateTime": "2021-01-28T23:17:38.400+00:00",
      "updates": [
        {
          "id": 123,
          "name": "Foo",
          "customId": null,
          "location": {
            "lat": 51.493601937687224,
            "lon": -0.12852029611716095
          },
          "positionsOccupancy": [
            {
              "customId": "",
              "groupId": 123,
              "id": 1,
              "location": {
                "lat": 51.49360068522545,
                "lon": -0.1286061268139623
              },
              "occupancyStatus": "Occupied",
              "statusChangeTime": "2021-01-28T23:17:38.400+00:00"
            }
          ],
          "summary": {
            "undefined": 0,
            "total": 1,
            "occupied": 1,
            "available": 0
          }
        }
      ]
    }
  }
}

updateSubscriptionArea

This mutation will update an existing subscription area.

All subscription area updates will extend expiration by 5 minutes from the current time.

You can also send empty mutation to only update the expiration.

Mutation

mutation MyMutation {
  updateSubscriptionArea(
    id: 1, 
    granularity: Position, 
    radius: 500
  ) {
    expiresOn
    id
    granularity
    location {
      lat
      lon
    }
    radius
  }
}

 

mutation ExtendSubscription {
  updateSubscriptionArea(
    id: 1, 
  ) {
    expiresOn
    id
  }
}

Response

{
  "data": {
    "updateSubscriptionArea": {
      "expiresOn": "2021-01-28T23:20:06.232134+00:00",
      "id": 1,
      "granularity": "Position",
      "location": {
        "lat": 51.49393,
        "lon": -0.12903
      },
      "radius": 500
    }
  }
}

{
  "data": {
    "updateSubscriptionArea": {
      "expiresOn": "2021-01-28T23:25:06.232134+00:00",
      "id": 1,
    }
  }
}

Use cases

Query

Use case

query MyQuery {
  findGroupOccupancies(
    lat: 0.0, 
    lon: 0.0, 
    radius: 2000
  ) {
    location {
      lat
      lon
    }
    summary {
      available
    }
  }
}

The summary object should be used to display availability for all parking group types

Displaying all parking groups within 2km in a mobile app

query MyQuery {
  groupOccupancy(id: 1) {
    positionsOccupancy {
      location {
        lat
        lon
      }
      occupancyStatus
    }
  }
}

Displaying individual parking positions when a user approaches his desired parking location

mutation MyMutation {
  createSubscriptionArea(
    granularity: Position, 
    lat: 1.5, 
    lon: 1.5, 
    radius: 2000
  ) {
    id
  }
}
subscription MySubscription {
  onSubscriptionAreaUpdates(
  id: <id from previous mutation>
  )
}

Displaying live parking statuses within 2km radius

mutation MyMutation {
  updateSubscriptionArea(
    id: 1, 
  ) {
    expiresOn
    id
  }
}

Extend subscription area expiration

Postman Collection

Download Postman Collection here:

Importing Collection

  1. Click import in My Workspace section.

  1. Upload the collection file and click

Import.

Adding API key to Postman Environment

This collection uses the api_key variable to add an authorization token to the x-api-key header.

  1. To create a new environment click on the eye icon near the top right corner.

2. Click Add to add a new environment.

3. Add the gql_api_key variable name and your token in the initial value.

4. Select the New Environment from the list.

5. You can now test the requests in the GraphQL Occupancy Collection.

  • No labels