HomeDocumentationRecipesChangelog
HomeRequest DemoContact
Documentation
HomeRequest DemoContact

GraphQL Basics

Validio API is powered by GraphQL, which is a query language for APIs to provide a flexible way to create custom queries and responses. To get you started quickly, here are some basic GraphQL concepts that might be good to know.

📘

Note

If you're new to GraphQL, a good starting point is the official Introduction to GraphQL.

Schema

One of the core features with GraphQL is that the API is defined with a schema. The schema describes types, interfaces, implementations, attributes and what functions or endpoints are available. It's a great way to see what input and output are expected by the API.

Objects and Types

Each operation (query, mutation or subscription) can consist of one or more objects used for constructing the request and the response as you want. An object describes types and their attributes.

A type has a name to describe what it is and optionally fields and types of the field. If the type ends with an exclamation mark (!) it means that the field is required and always has to be present.

type Hobby {
  name: String!
  timesPerWeek: Int
}

type Person {
  name: String!
  age: Int!
  phone: String
  hobbies: [Hobby!]
}

Operations

When interacting with a GraphQL you use operations to describe your request: queries, mutations or subscriptions.

  • Queries are used to fetch data.
  • Mutations are used to create, delete or update data.
  • Subscriptions are used to stream data from the server over a long lived request, similar to gRPC streams or websockets.

📘

Note

A query is also an object in GraphQL. The queries are a bit special, because they are a root object and describe the entry point of every given query.

The following example shows how a query is defined. The request accepts an input type of ListPersonsInput which can be used to pass a payload to the server and that the server will respond with a list of persons. In this query, the input type is an object used to represent the payload, and the list ends with an exclamation mark so there will always be a list and never null.

type ListPersonsInput {
  hasAtLeastOneHobby: Boolean!
}

query {
  listPersons(input: ListPersonsInput!) [Person!]!
}

Interfaces

An interface describes characteristics of an object that can be shared across multiple types. This is used when a resource can have multiple variants, just like objects in object oriented programming. An example of this can be an animal interface that describes shared attributes across animals but each animal has its own implementation with specific attributes for them.

interface Animal {
  name: String!
  age: Int!
}

type Cat implements Animal {
  name: String!
  age: Int!
  legs: Int!
}

type Fish implements Animal {
  name: String!
  age: Int!
  fins: Int!
}

query {
  listAnimals() [Animal!]
}

When you query for an animal and want to specify your data, you need to specify what to do given each implementation.

query ListAnimals {
  listAnimals {
    name
    age
    ... on Cat {
      legs
    }
    ... on Fish {
      fins
    }
  }
} 

Fragments

You will sometimes see fragments being used in our documentation. Fragments are reusable building blocks that can help you build complex queries and inline the definitions. For more information about fragments, refer to GraphQL documentation.

In the following example, a fragment on a Person can be reused for all fields that returns a Person.

fragment PersonDetails on Person {
  name
  age
}

query GetPerson(id: PersonId!) {
  person(id: $id) {
    siblings {
      ... PersonDetails
    }
    parents {
      ... PersonDetails
    }
    friends {
      ... PersonDetails
    }
  }
}

Caveats

If you’re new to GraphQL there are some things that are good to know other than what it is and how it’s designed. Especially coming from a RESTful background some things might not be obvious. This is a list of common things new users run into.

Field names must be unique

When spreading specific implementations of an interface, that is when an endpoint can return multiple types, and they share the same field name, you must use an alias on one of them so all field names are unique. An alias is created by specifying a name followed by a colon before the field you’re selecting:

query MyQuery {
  listResource {
    id
    ... on TypeOne {
      typeOneValue: value
      width
    }
    ... on TypeTwo {
      typeTwoValue: value
      height
    }
  }
}

Requests can be batched

In GraphQL you don’t need to send each query separately, you can batch multiple queries and have them all executed in the same request. When doing this for queries and reading data, they’re even run in parallel to speed up the request! When mutating objects however they’re always executed in sequential order.

You can find an example on how to batch requests when updating the name and threshold of a validator in the Validio SDK Recipes.