GraphQL

URL prefix

We are separating the APIs with URL prefixes.

The prefix for this API is: /graphql

The endpoint remains constant no matter what operation you perform.

What is GraphQL

Learn more about GraphQL from the official documentation

Exploring with GraphiQL / Playground

You can explore the graph with GraphiQL by going to your www.your-backend-url.com/graphiql, www.your-backend-url.com/playground, or by getting the schema using your ide of choice.

For a more visual exploring you can also visit: www.your-backend-url.com/documentations/graphql

Here are some IDE choices:

GraphQL terminology

Query

A query READ information from the graph.

Mutation

A mutation CREATE/UPDATE/DESTROY information. Jump to example

Fields

A field is a unit of data you can retrieve from an object. As the official GraphQL docs say: “The GraphQL query language is basically about selecting fields on objects.”

Connection

Connections let you query related objects as part of the same call. With connections, you can use a single GraphQL call where you would have to use multiple calls to a REST API.

It’s helpful to picture a graph: dots connected by lines. The dots are nodes, the lines are edges. A connection defines a relationship between nodes.

Edge

Edges represent connections between nodes. When you query a connection, you traverse its edges to get to its nodes. Every edges field has a node field and a cursor field. Cursors are used for pagination.

Node

Node is a generic term for an object. You can look up a node directly, or you can access related nodes via a connection. If you specify a node that does not return a scalar, you must include subfields until all fields return scalars.

Inline Fragments

If you are querying a field that returns an interface or a union type, you will need to use inline fragments to access data on the underlying concrete type.

Authentication

GraphQL requests must be authenticated using an API Access Token. Pass the token in your GraphQL request using the Authorization HTTP header with a value Bearer token.

To create a token see the authentication information page

To query GraphQL using cURL, make a POST request with a JSON payload. The payload must contain a string called query. See the example above.

curl --request POST \
 --url https://example.com/graphql \
 --header 'authorization: Bearer YOUR_TOKEN' \
 --header 'content-type: application/json' \
 --data '{"query":"{ viewer{ fullName } }","variables":{}}'

Scopes

The GraphQL endpoint provides two root queries: viewer and app.

Viewer query

The viewer query provides data from the viewpoint of the end user. Jump to examples

App query

The app query provides all data. To use the app scope you must create an api application in the backend and provide the relevant tokens. Jump to examples

To see the app scope in /playground you can add your bearer token to the http headers section:

{
  "Authorization": "Bearer your-token-here"
}

Examples

For simplicity we only show the JSON body content that you can paste in your application of choice.

Basic viewer information

query {
  viewer {
    id
    fullName
    email
    externalIdentifier
  }
}

Create a user with external_authentication_token

With app scope mutation

mutation {
  userCreate(fullName: "MyFull Name", email: "some@email.com",locale: "de", timezone: "Berlin", externalAuthenticationToken: "randomHash") {
  user{
    fullName
  }
}

Viewer units

Finding a users accessible units

{
  viewer {
    fullName
    accessibleUnits{
      nodes{
        id
        name
      }
    }
  }
}

Viewer units - passing variables

To find a users bookable units, you can pass a variable to the object.

{
  viewer {
    fullName
    accessibleUnits(bookables: true){
      nodes{
        id
        name
      }
    }
  }
}

You can also limit the amount of returned objects

{
  viewer {
    fullName
    accessibleUnits(first: 3){
      nodes{
        id
        name
      }
    }
  }
}

Viewer IOT Devices

Iot Devices are unions, which means that you can get different objects in return. Using the ... on TypeName style syntax you can specify the information you want per object.

GraphQL allows you to request__typename, a meta field, at any point in a query to get the name of the object type at that point.

{
  viewer {
    fullName
    accessibleUnits() {
      pageInfo {
        endCursor
      }
      nodes {
        actuators {
          ... on SensorbergLock {
            name
          }
        }
        id
        name


        iotDevices {
          __typename
          ... on LightBulb {
            id
            name
            targetState {
              __typename
              ... on Power {
                value
              }
              ... on Intensity {
                value
              }
            }
            currentState {
              __typename
              ... on Power {
                value
              }
              ... on Intensity {
                value
              }
            }
          }
          ... on Heater {
            id
            name

            currentState {
              __typename
              ... on Temperature {
                value
              }
            }

            targetState {
              __typename
              ... on Temperature {
                value
              }
            }
          }
          ... on CustomIotDevice {
            id
            name
            currentState {
              __typename
              ... on Power {
                value
              }
              ... on Position {
                value
              }
              ... on Angle {
                value
              }
              ... on Open {
                value
              }
            }
            targetState {
              __typename
              ... on Power {
                value
              }
              ... on Position {
                value
              }
              ... on Angle {
                value
              }
              ... on Open {
                value
              }
            }
          }
        }
      }
    }
  }
}

Basic app information

The app scope starts of by exposing Users and Units.

As can be seen in the example below, it is possible to find specific users by specifying an array of externalIdentifiers or ids. This is also possible for the units.

In the app scope the Units ancestry can be followed by getting its children or parent

{
  app {
    name
    users (externalIdentifiers: ["exteral-id-1", "exteral-id-2"]) {
      nodes{
        fullName
        externalIdentifier
      }
    }
    rootUnits (externalIdentifiers: ["exteral-id-1", "exteral-id-2"]){
      nodes{
        name
        children{
          nodes{
            name
            children{
              nodes{
                name
              }
            }
          }
        }
      }
    }
  }
}

Card Assignments

Here is an example show card assignments for users

{
  app {
    name
    users(first: 3) {
      nodes{
        fullName
        cardAssignments {
          id
          card {
            __typename
            ... on BeaconCard {
              name
              proximityUuid
              major
              minor
            }
            ... on NfcCard {
              name
              nfcIdentifier
            }
            ... on IdentificationCode {
              name
            }
          }
        }
      }
    }
  }
}

Mutations Examples

Create user

The following mutation creates a user and returns his id, fullName and externalIdentifier

mutation{
  userCreate(
    fullName: "John Example",
    email: "john.example@example.com",
    locale: "de",
    timeZone: "Berlin",
    externalIdentifier: "external-id-for-john-example"
  ){
    user{
      id
      fullName
      externalIdentifier
    }
  }
}

Delete user

To delete a user call the userDelete mutation providing either the externalIdentifier or ID

mutation {
  userDelete(externalIdentifier: "external-id-for-john-example") {
    user {
      id
    }
  }
}

Update user

To update a user call the userUpdate mutation providing either the the externalIdentifier or ID

mutation {
  userUpdate(
    id:"480de7f3-930c-4e82-b653-c263600f5b86",
    fullName: "John E. Example",
    externalIdentifier: "new-external-id-for-john-example"
  ) {
    user {
      id
      fullName
      email
      locale
      timeZone
      externalIdentifier
      externalAuthenticationToken
    }
  }
}