Technical Advisors: Working with the Sourcegraph GraphQL API
Intended Audience
This document is mainly geared towards external users of the Sourcegraph GraphQL API, not for internal Sourcegraph developers. Some external users are folks in Technical Success or even customers themselves.
What GraphQL is and isn’t
It is:
- A query language for APIs
- Provides exactly what you ask for. No more, no less.
- This is called over/underfetching data
- Strongly typed
- Versionless
It isn’t:
- A query language for databases
- It isn’t a language for Graph Databases (like Neo4j)
- A solution for world hunger…unfortunately
Anatomy of a GraphQL Query/Operation
Operation Type: Query, Mutation, or Subscription. Describes the type of operation you’re trying to do.
Operation Name: Optional descriptor that identifies the operation, typically for debugging or server-side logging
Variable Definition: Dynamic parts that typically change between requests and can be defined externally or in-line
Variable Type / GraphQL Type: The data structure of the variable or of a type, as defined in the GraphQL Schema
Nullability: Determine whether or not a field or variable is allowed to be null
Fields: Building blocks that represent the data being returned
Arguments: Either pulled in from a Variable Definition or in-line, these specify key-value pairs that affect how a Field is resolved
(Inline) Fragments: Encapsulated pieces of shared query logic
Sourcegraph’s GraphQL Schema & Documentation
Sourcegraph’s GraphQL API is defined by its schema or SDL (Schema Definition Language).
Explore the Sourcegraph GraphQL API documentation here
- These docs are auto-generated, for more details join #wg-graphql-docs
- There are some types, fields, and fragments that exist in the API but are undocumented, raise it to that Slack channel
Setting up your GraphQL IDE
Apollo Sandbox is great for navigating through a complex GraphQL schema and has great developer experience for crafting queries
- Navigate to Apollo Studio Sandbox and click Open Connection Settings in the top left corner
- Under Endpoint input
https://demo.sourcegraph.com/.api/graphql
and click Save
- On the bottom of the IDE, click Headers and create an
Authorization
header key with the value in the format:token "Your Demo Token"
- Now you have easy one-click crafting of your GraphQL queries and Schema reference! 🎉
Navigating the Schema
When you’ve set up your Apollo Sandbox environment successfully, you should have access to the GraphQL schema reference page.
This page is incredibly instrumental in being able to understand and navigate the objects and types that are available in the API.
Simply search for the objects or types you’re looking for to see how to access them.
By searching for a Batch under the Query
root type, you can see all objects that are available with “batch” in the name or documentation
Clicking into BatchChange gives me all the fields that are available under that object and also how to access it.
Understanding Fragments
A Fragment is a power filtering mechanism that takes advantage of the strongly typed nature of GraphQL schemas
Consider the below operation:
query Search($query: String!) {
search(query: $query, version: V3) {
results {
results {
... on FileMatch {
...FileMatchFields
}
}
}
}
}
fragment FileMatchFields on FileMatch {
repository {
name
url
}
file {
name
path
url
}
}
... on File Match
The above notation takes advantage of the strongly typed nature of GraphQL.
What this means is “of the returned data from the parent, if the type is of FileMatch
, return the following fields…”
...FileMatchFields
This fragment notation is a way to improve readability of your GraphQL operation.
It is a shorthand way to add fields into an operation. The fragment FileMatchFields on FileMatch
later on in the operation body defines the fields that are to be requested.
Understanding Pagination
There are some objects in the API that return lots of data. Sourcegraph utilizes a cursor based pagination pattern somewhat based on the Relay-spec.
Consider the below operation:
//Get the first 10 insights' IDs
query Insights($first: Int, $after: String) {
insightViews(first: $first, after: $after) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
}
}
}
//Query Variables
{
"first": 10,
"after": null
}
Paginated data is accessed through nodes
Pass the nodes.id
field into subsequent calls in the $after
variable to paginate through data that occurs after that Object. See operation below for an example.
pageInfo
and totalCount
can tell you how much data is left
//Get the next 5 insights after a specific insight
query Insights($first: Int, $after: String) {
insightViews(first: $first, after: $after) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
}
}
}
//Query variables
{
"first": 5,
"after": "aW5zaWdodF92aWV3OiIyNU9lanpQZUVWZ1ViMk96NzNYdnF4TnVvdUci"
}
endCursor
will always return the last ID in your call so you can use that in subsequent calls until hasNextPage
is false
.
Tips & Tricks
- Make use of your browser’s developer tools to determine the GraphQL operation within Sourcegraph’s web app.
-
Check out the
Node
documentation to see what parts of the API require pagination -
Use the Copy Operation Link when right clicking into Sandbox to collaborate with other folks who have the IDE configured
Example GraphQL Operations
The below operations will use
demo.sourcegraph.com
. Adjust to your connection details and variables as necessary
Example scripts that utilize the GraphQL API
Ensure you’re part of the Sourcegraph GitHub organization to view these private scripts