Skip to content

@bb_resolver

@bb_resolver defines how a GraphQL operation should be resolved - or "carried out" in other terms.

Syntax

OperationDefinition
    @bb_resolver(
      _type: TypeSpecifier
          TypeSpecifierArguments
    )

Where:

OperationDefinition

Definition of the GraphQL operation; this is standard GraphQL syntax, see here

TypeSpecifier

Specifies the type of resolver function to perform for this operation.
Type: Enum
Value: One of Select | Insert | InsertNested | Update | UpdateNested | Delete | Orchestrator | AuthManagement | HttpService

Depending on the type specified with TypeSpecifier, a set of arguments are required and/or available (TypeSpecifierArguments).

DB Operation Arguments

Definition of arguments for TypeSpecifier = Select | Insert | InsertNested | Update | UpdateNested | Delete.

_object

ObjectType; a previously defined type that this operation should primarily operate on. For instance, if this operation should create an object, specify the object's type here.

_filter

ObjectFilterSpecifier; defines a filter that limits the objects this operation is applied to. Only applicable if TypeSpecifier is Select | Update | UpdateNested | Delete.

_fields

FieldsSpecifier; specifies which fields are available or the operation and where their content comes from.

_object

The type of object this operation works on. Refers to a type defined before.

Example:

type Patient {
  id: ID,
  name: String!
}

type query {
  # gets a single patient record given the patient ID
  getPatient(patientId: ID!): Patient
  @bb_resolver(
      _type: SELECT
      _object: Patient
      _filter: { id: { _eq: "$patientId" } }
  )
}

_filter

Specifies filter settings for operations that require a selection set; uses GraphQL object syntax.

Syntax:

{
  fieldName: {
    comparison-specifier: value
  }
}
fieldName

Name of the field to filter by or search. This field must be defined in the object type specified in _object.

Comparison Specifier

Specifies how the comparison should be performed. See list below.

_eq

field must match value

_neq

field must not match value.

_gt

field must be greater than value; strings must sort behind value.

_gte

field must value; strings must sort same or behind value.

_lt

field must value; strings must sort before value.

_lte

field must value; strings must sort same or before value.

_in

field must be contained in value.

_nin

field must not be contained in value.

_like

field must be LIKE value; allows a wildcard search using % as the wildcard.

_nlike

field must not be LIKE value; allows a wildcard search using % as the wildcard.

Example:

type query {
  activePatients(nameLike: ID!): [Patient]
  @bb_resolver(
      _type: SELECT
      _object: Patient
      _filter: { 
        name: { 
          _like: "$nameLike" 
        }
        active: {
          _eq: "true"
        } 
      }
  )
}

_fields

Examples

Basic SELECT resolver example
type Patient {
  id: ID!
  name: String
}

# gets a single patient record given the patient ID
getPatient(patientId: ID!): Patient
@bb_resolver(
    _type: SELECT
    _object: Patient
    _filter: { id: { _eq: "$patientId" } }
)
In this simple example, we define a getPatient operation that gets a single patient given the patient ID. The resolver would query the patient table in the database corresponding to the Patient object in the GraphQL schema and fetch a patient record for the ID provided.

Basic INSERT resolver example using an input object
type Patient {
  id: ID!
  firstName: String
  lastName: String
  age: Int
}

input PatientInput {
  firstName: String
  lastName: String
  age: Int
}

type Mutation {
  # inserts a patient record given a patient input object
  insertPatient(patientData: PatientInput!): Patient
    @bb_resolver(
      _type: INSERT
      _object: Patient
      _fields: { 
        firstName: "$patientData.$firstName"
        lastName: "$patientData.$lastName"
        age: "$patientData.$age"
      }
    )
}

In this example we're performing an insert into the Patient table. We are also using an input object instead of scalar arguments to provide the insert data; this is done purely for illustration purposes on using input objects. Note the format of the arguments when using input objects (i.e. $input_object.$input_object_field_argument).

Orchestrator

The orchestrator type allows you to join multiple other operations into one operation. Here's a basic example to illustrate the point:

Orchestrator example
type Mutation {
  insertSubscription(name: String!, amount: Float!): Subscription
    @bb_resolver(
      _type: DELETE
      _object: Subscription
      _filter: { id: { _eq: "$id" } }
    )

  deleteSubscription(subscription_id: ID!): Void
    @bb_resolver(
      _type: DELETE
      _object: Subscription
      _filter: { id: { _eq: "$subscription_id" } }
    )

  replaceSubscription(old_id: ID!, new_name: String!, new_amount: Float!): Void
    @bb_resolver(
      _type: ORCHESTRATOR
      _steps: [
        {
          _mutation: "deleteSubscription"
          _arguments: {
            subscription_id: "$old_id"
          }
        }
        {
          _mutation: "insertSubscription"
          _arguments: {
            name: "$new_name",
            amount: "$new_amount"
          }
        }
      ]
    )
}
An orchestrator has one specifier, the _steps specifier that defines the different operations involved in the orchestrator. There are two steps in the example above. Each step is furthermore made up of the operation name (indicated by the _mutation specifier) and the _arguments specifier that allow you to map arguments from the orchestrator operation to the arguments of the step operation.

Note, currently, can only have mutations in orchestrators. Also, nested orchestrators, i.e. orchestrators within another orchestrator, is not supported.

AuthManagement

See AuthManagement.

HttpService

Define a microservice that should resolve the operation.

The microservice gets the unmodified GraphQL request from basebox and must obviously be able to handle it and return a proper JSON response.

See also the Microservices Guide.

Arguments

_url

The URL of the GraphQL endpoint basebox should POST the GraphQL request to.

_passthrough_headers

A list of HTTP header names that should be passed through to the microservice.
Type: List of Strings
Example: [ "X-Forwarded-For", "X-Forwarded-Proto" ]
If a header name is not found in the original request, broker uses the string --header not found in client request-- for this header name instead.

GraphQL Request

basebox POSTs the current GraphQL request as-is to the microservice and returns its response to the client without modifying it.

The current user's access token is added to the Authorization HTTP header field as a base64 encoded string.

Security Warning

The microservice is responsible to verify that the user has all required access rights to perform the operation. This must be done by looking at the fields in the decoded access token.