Skip to main content

Overview of GraphQL

Kavitro API is fully built with GraphQL, which is a flexible query language that allows you to specify as much or as little data as you need. Learn more about GraphQL from the GraphQL Foundation introduction

GraphQL stands for Graph Query Language, but unlike other query languages such as SQL (Structured Query Language), it is not a language for communicating directly with a database, but rather a language that defines a contract through which a client communicates with an API server.

Architecture

Unlike REST APIs, a GraphQL API is defined with a single endpoint, which can access the full capabilities of the GraphQL server.

Requests made to a GraphQL server are called documents and consist of operations such as queries (for read requests) and mutations (for write requests).

GraphQL over REST

GraphQL and REST are not interchangeable concepts, but at the end of the day they solve similar problems for applications. REST stands for Representational State Transfer, and is a software architectural style for sharing data between different systems. A RESTful API is an API that adheres to the principles and constraints of REST, which includes being stateless, cacheable, enforcing a separation of concerns between the client and server, and having a uniform interface, such as through URIs. GraphQL, as covered previously, is a specification for a query language and runtime for executing queries.

As with everything there are advantages and disadvantages to both systems, and both have their use in modern API development. However, GraphQL was developed to combat some perceived weaknesses with the REST system, and to create a more efficient, client-driven API.

  • Architecture - A REST API is typically defined by multiple endpoints on a server, but GraphQL exchanges data over a single endpoint. A GraphQL endpoint can return a complex graph of data that might require multiple REST queries, reducing the number of requests over the network for a single view.
  • Data fetching - A REST API returns the set of data that was determined on the server. This might be far too much data, such as if the view only requires one property from a response. It also might not be enough, such as a list endpoint that doesn't return every property that a table requires in the view. GraphQL prevents this over and under fetching of data via declarative queries.
  • Error handling - Since it is not necessary for GraphQL to be served over HTTP, there is no specification about using HTTP response codes for errors. Typically all GraphQL endpoints will resolve with a 200 HTTP code response, and failed results will include an errors property alongside the data property in the response. RESTful APIs, on the other hand, utilize different 400 level HTTP codes for client errors and 200 level HTTP codes for successful responses. Kavitro follows the GraphQL convention, with a small number of rejections that answer with a non-200 status instead. See error handling.

This list does not cover all the similarities and differences between REST and GraphQL, but summarizes many of the most critical points.

How this applies to Kavitro

The general points above hold for any GraphQL API. These are the specifics of ours.

One endpoint. Every query and mutation is a POST to https://api.kavitro.com/graphql. There are no resource paths, and the operation you are performing is described entirely by the document you send. See making a request.

Lists are connections. Every list field is paginated and returns edges and pageInfo rather than a bare array, and page sizes are capped. See pagination.

Deletes are reversible. Records are soft-deleted rather than removed, which is why there is a restore mutation for most resources and a trashed argument on most lists. A "deleted" record is hidden, not gone. See mutations.

Introspection is disabled. The usual trick of querying the schema from a client will not work here, and neither will tools that depend on it. Use the API Reference instead - it is generated from the live schema, so it is exactly as current.

Requests are bounded in several directions at once. Beyond the request rate limit, a single query is measured for cost, size and depth, and mutations have their own separate budget. See rate limits.