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 stateid
- position idcustomId
- user-defined idgroupId
- position’s group idoccupancyStatus
- parking space occupancy statusstatusChangeTime
- latest occupancy status change timelocation
- object containing latitude and longitude coordinates
GroupOccupancy
- describes a group, its positions and their occupancy statesid
- group idname
- group user-defined namecustomId
- group user-defined idlocation
- object containing latitude and longitude coordinatespositionsOccupancy
- list of all positions inside a group with its occupancy informationsummary
- 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 areaid
- area idlocation
- object containing latitude and longitude coordinatesradius
- area’s radius in metersgranularity
- 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:
granularity: Position → updates { … on PositionOccupancy }
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
Click import in My Workspace section.
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.
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.