Skip to content

Ultrastructure GraphQL API

Constantine edited this page Oct 2, 2015 · 4 revisions

This page describes the Ultrastructure GraphQL API endpoint.

What is GraphQL?

One of the great things about GraphQL is that it is from Facebook. The great thing about that is they have lots of people who know how to write and talk about GraphQL. It is well worth your while to browse through teh Google and see what you can find. There's some good stuff out there.

How Is GraphQL Integrated Into Ultrastructure?

That's a very good question, I'm glad you asked.

Workspaces As GraphQL Schema Namespaces

The GraphQL resource endpoint (/graphql/workspace/<workspace uuid/uri>) is partitioned by workspace. Ultrastructure workspaces provide a conceptual handle that defines a GraphQL Schema of Types derived from the workspace.

Phantasms As GraphQL Schema Types

In Ultrastructure, one does not define a GraphQL schema. Rather than the GraphQL schema is generated by the Facets defined in that workspace. GraphQL as defined by Facebook provides a flat query namespace. By naturally partitioning the GraphQL query endpoint by workspace, we can provide a nicely sophisticated mechanism for partitioning the Types and providing some measure to prevent namespace explosion.

The Facets defined in a workspace are represented by generated GraphQL Types. These Types define a set of top level query and mutation types that clients may issue GraphQL queries and mutations to.

Generated Queries

For every declared Facet in the workspace, we generate the following queries. We'll use <F.Name> as the name the Phantasm has been given in the workspace.

  • <F.Name> - The top level query for an instance of the Phantasm
  • InstancesOf<F.Name> - Retrieves all the instances of a Phantasm

The mutation queries generated are:

  • Create<F.Name>
  • Update<F.Name>
  • Apply<F.Name>
  • Remove<F.Name>

Northwind Query Example

Using the Northwind mashup's workspace definition, here is the query used in a master/detail view of a Customer's orders to get all the customers:

{ InstancesOfCustomer { customerName id description } }

This returns all the agencies that are classified as Customers. For example:

{
  "errors": [],
  "data": {
    "InstancesOfCustomer": [
      {
        "customerName": "George Washington University",
        "id": "3de0f23d-6571-11e5-90a2-674877f404ee",
        "description": "Georgetown University"
      },
      {
        "customerName": "Cafleur Bon",
        "id": "3de0f23f-6571-11e5-90a2-674877f404ee",
        "description": "Carfleur Bon"
      },
      {
        "customerName": "Der Org A",
        "id": "3de11953-6571-11e5-90a2-674877f404ee",
        "description": "Organization A"
      }
    ]
  }
}

Now that we have all the instances, we can get the detail of a Customer's orders using this query:

query customers($id: String!) { 
  Customer( id: $id) { 
    orders {
      id 
      name
      requiredDate
      orderDate
      shipDate 
      itemDetails { 
        id 
        name
        unitPrice 
        quantity 
        product { 
          id name 
        } 
      }
    }
  }
}

Note that the query is parameterized with the id of the customer. Supplying the id as the query variable returns you:

{
  "errors": [],
  "data": {
    "Customer": {
      "orders": [
        {
          "id": "4a7947ab-6571-11e5-942c-33a8e9bdde29",
          "name": "Cafluer Bon Order",
          "requiredDate": null,
          "orderDate": "2015-09-27 16:41:36.063",
          "shipDate": null,
          "itemDetails": [
            {
              "id": "4a9ef83b-6571-11e5-942c-33a8e9bdde29",
              "name": "an item",
              "unitPrice": 1250.1,
              "quantity": 2,
              "product": {
                "id": "3de13f83-6571-11e5-90a2-674877f404ee",
                "name": "Abc486"
              }
            },
            {
              "id": "4abcb976-6571-11e5-942c-33a8e9bdde29",
              "name": "an item",
              "unitPrice": 10.25,
              "quantity": 50,
              "product": {
                "id": "3de16695-6571-11e5-90a2-674877f404ee",
                "name": "ChemB"
              }
            }
          ]
        },
        {
          "id": "30c1c35b-685d-11e5-8faf-1f20babe46c0",
          "name": "Cafluer Bon Order",
          "requiredDate": null,
          "orderDate": "2015-10-01 09:55:16.481",
          "shipDate": null,
          "itemDetails": [
            {
              "id": "30dc776b-685d-11e5-8faf-1f20babe46c0",
              "name": "an item",
              "unitPrice": 1250.1,
              "quantity": 2,
              "product": {
                "id": "3de13f83-6571-11e5-90a2-674877f404ee",
                "name": "Abc486"
              }
            },
            {
              "id": "30f618f6-685d-11e5-8faf-1f20babe46c0",
              "name": "an item",
              "unitPrice": 10.25,
              "quantity": 50,
              "product": {
                "id": "3de16695-6571-11e5-90a2-674877f404ee",
                "name": "ChemB"
              }
            }
          ]
        },
        {
          "id": "310f7985-6917-11e5-a55f-c94be3cca620",
          "name": "Cafluer Bon Order",
          "requiredDate": null,
          "orderDate": "2015-10-02 08:06:43.371",
          "shipDate": null,
          "itemDetails": [
            {
              "id": "31265d05-6917-11e5-a55f-c94be3cca620",
              "name": "an item",
              "unitPrice": 1250.1,
              "quantity": 2,
              "product": {
                "id": "3de13f83-6571-11e5-90a2-674877f404ee",
                "name": "Abc486"
              }
            },
            {
              "id": "313d4070-6917-11e5-a55f-c94be3cca620",
              "name": "an item",
              "unitPrice": 10.25,
              "quantity": 50,
              "product": {
                "id": "3de16695-6571-11e5-90a2-674877f404ee",
                "name": "ChemB"
              }
            }
          ]
        }
      ]
    }
  }
}

Clone this wiki locally