/camunda-bpm-graphql

GraphQL for Camunda BPM

Primary LanguageJava

Camunda GraphQL

Camunda GraphQL is a Community Extension for Camunda BPM that allows you to use GraphQL to query and mutate Process Engine data in a simple way.

Overview

Release 0.3.0

  • update to Spring Boot 1.5.7
  • update to GraphQL Java Tools 4.1.2
  • add GraphQL Spring Boot Starter
  • add GraphiQL Spring Boot Starter
  • GraphiQL endpoint default set to /camunda-graphql/graphiql
  • GraphQL endpoint default set to /camunda-graphql/graphql
  • Simplification of GraphQL Schema (remove Interfaces like TaskEntity)
  • cleanup of a Mutation
  • add Mutation startProcessInstanceByMessage
  • claimTask returns updated Task
  • refactor Test setup
  • update Documentation

Build the GraphQL server

  1. Ckeckout or Clone this repository using Git
  2. Adapt src/main/resources/application.properties:
  3. Build the project
    for Apache Tomcat: mvn clean package
    for JBoss WildFly use the profile wildfly: mvn clean package -Pwildfly

Install the GraphQL server

Tomcat installation

  • Get the latest Release (.war file) from the Camunda Repo
  • deploy it to your Tomcat server e.g. copy it to the Tomcat /webapps` folder

Wildfly installation

For WildFly you have to clone the project and build the .war file.
See chapter Build the GraphQL server.

Test the Installation

Access the GraphQL endpoint with a browser

Access the GraphQL endpoint with GraphiQL an in-browser IDE for exploring GraphQL

Other GraphQL clients

Beside the build-in GraphiQL you can use other GraphQL clients.
Basically...

  • ...point your GraphQL client to the GraphQL server endpoint:
    http://<server-name>:<PORT>/camunda-graphql/graphql
  • depending on the GraphQL server authentication settings you need to add Authentication Header to your requests

Examples of other GraphQL clients:


GraphQL Queries and Mutations

Query Tasks:

query tasks

Query Tasks using a Filter:

query tasks with filter

Query Process Instances:

query proceses

Query Process Instance Variables:

query proceses with vars

Query Task Variables:

query tasks with vars

Mutation
Assign a user to a task

setAssignee mutation

Mutation
Start a Process Instance with start variables
startProcessInstance

GraphQL Schemas and Types

A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.

Docs Schema

Docs Root Types

Currently defined queries:

Docs Queries

Currently defined mutations:

Docs Mutations

Defining / Extending the Camunda GraphQL Schema

We decided to use the Schema Definition Language (a GraphQL DSL) to define the Camunda GraphQL schema instead of coding it in Java.
The Schema Definition Language is very easy to understand.
For example this is the Type Definition of the Camunda Task:


graphqls TaskEntity

To get an understanding of Schemas please visit:

The Camunda GraphQL Schema is comprised of several schema files located at src/main/resource/*.graphqls.
This is an attempt to group GraphQL Type Definitions by topics

schema files overview

The so called Root Types serve as entry points for Queries and Mutations (in the future: Subscriptions etc.)

The Root Types schema file is src/main/resources/camunda.graphqls

Introspection

For interactive GraphQL code completion, build-time validation, GraphQL Schema stiching or other fancy things
any GraphQL client can use GraphQLs Introspection to retrieve the whole or parts of the Servers GraphQL Schema.

This is a possible and probably quite complete Introspection Query (from GraphQL Voyager):

query IntrospectionQuery {
    __schema {
      queryType { name }
      mutationType { name }
      subscriptionType { name }
      types {
        ...FullType
      }
      directives {
        name
        description
        locations
        args {
          ...InputValue
        }
      }
    }
  }

  fragment FullType on __Type {
    kind
    name
    description
    fields(includeDeprecated: true) {
      name
      description
      args {
        ...InputValue
      }
      type {
        ...TypeRef
      }
      isDeprecated
      deprecationReason
    }
    inputFields {
      ...InputValue
    }
    interfaces {
      ...TypeRef
    }
    enumValues(includeDeprecated: true) {
      name
      description
      isDeprecated
      deprecationReason
    }
    possibleTypes {
      ...TypeRef
    }
  }

  fragment InputValue on __InputValue {
    name
    description
    type { ...TypeRef }
    defaultValue
  }

  fragment TypeRef on __Type {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
                ofType {
                  kind
                  name
                }
              }
            }
          }
        }
      }
    }
  }



The response of the above Introspection Query can be pasted into tools like GraphQL Voyager as a Custom Schema and within seconds you get a graphical representation of your Schema, like so:

graphical GraphQL Schema

Awesome!

Authentication

The Camunda GraphQL server supports three Authentication methods:

Properties which manage authentication are:

  • auth.Filter
  • JWT.secret
  • JWT.issuer

These properties can be set as

  • JNDI attributes from java:comp/env
  • Java System properties
  • OS environment variables
  • properties in application.properties

E.g. if you are using Tomcat you can add them to catalina.properties.

If authentication is switched on (Basic or JWT) the Camunda GraphQL Server expects an Authorization-Header in the client request.
GraphQL clients let you define these request headers, e.g. the graphiql-app has a link _Edit HTTP headers

http headers 01

http headers 02

Basic Authentication

To switch to Basic Authentication use:
auth.Filter=BASIC

For example if you have a Camunda user demo with the password demo your Authorization-Header must be:
Key=Authorization
Value=Basic ZGVtbzpkZW1v (why?)


JWT (JSON Web Token) Authentication

To switch to JWT you must set three properties:
auth.Filter=JWT
JWT.secret=Whatever_Random_Secret_String_You_Prefer
JWT.issuer=Usualy_The_Name_Of_Your_Company

A JWT Authorization-Header could look like this:
Key=Authorization
Value=Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJjYW11bmRhIiwiZXhwIjoxNDk3NzA4NjY3LCJpYXQiOjE0OTc2MjIyNjcsInVzZXJuYW1lIjoiZGVtbyJ9.Z-7NTGsHYqsEoc98yOgeT5LD9oGnei6jDPs-FQQhqDw

Important!
The GraphQL Server can validate existing JSON Web Token presented in the Authorization-Header based on
JWT.secret
JWT.issuer
(future releases will support private/public key)
but cannot provide or issue them. There is no login functionality "out of the box"
There is no JWT provider build into Camunda GraphQL server, because that does not belong to GraphQL at all.

Workaround (in case you do not have a JWT provider)
To create valid JWTs you need a JWT provider.
A JWT provider for Camunda can be found here: https://github.com/Loydl/camunda-jwt-provider

The JWT.secret and JWT.issuer settings of the

  • JWT provider
  • and the Camunda GraphQL server

must be the same, otherwise the JWT cannot be validated and user do not get authenticated.
(BTW, this is also a good option to basically implement Single Sign On).

Further information about JWT: https://jwt.io

No Authentication

To switch off authentication you simply set:
auth.Filter=NO
or delete this property, e.g. in catalina.properties put it in a comment:
#auth.Filter=xyz
(If the value of auth.Filter is equal JWT or BASIC than authentication is switched on, otherwise it is switched off.)

Goals

  • expose the complete Camunda Java API in GraphQL
  • build modern web and mobile clients for Camunda BPM (freedom to choose your GUI library)
  • build GraphQL-based, customizable versions of Tasklist, Cockpit, Admin
  • Camunda BPM as part of a micro-services architecture. Service accessible through a GraphQL endpoint
    (using GraphQL Schema Stiching to combine many GraphQL endpoints to one GraphQL API gateway)
  • Realtime GUIs (add GraphQL subscriptions to Camunda GraphQL)

Camunda Forum Thread (initial)

https://forum.camunda.org/t/developing-the-camunda-graphql-extension