A primer on GraphQL

Crom's GraphQL endpoint is located at: https://api.crom.avn.sh/graphql.

This API is considered to be in an alpha state, and can change or require authorization at any point in the future. If you want to use the API in a production application, please join the discord server and tell me about your application.

Say hello to GraphQL

Crom's API is powered by a relatively new query language: GraphQL. GraphQL lets you take full advantage of Crom's heavily relational architecture and lets you ask complex nested questions like "what is the rating of the latest page created by the author of SCP-5000?" without having to make multiple requests.

Press "Open in playground" below and then the play button to get the answer to that question. Give it a try!

# ↓ This is a query. You don't have to give it a name, but it
# helps.
query ThatQuestionWeJustAsked {
# ↓ This is a field. Some fields can have optional or
# required arguments. Some fields have child fields and you
# need to select precisely the ones you need. Here, we just
# want the "attributions" field on the page.
page(url: "http://scp-wiki.wikidot.com/scp-5000") {
attributions {
user {
# ↓ "name" returns a string, so there's nothing further
# to select.
name
attributedPages(
sort: { key: CREATED_AT, order: DESC }
first: 1
) {
edges {
node {
url
wikidotInfo {
title
rating
}
}
}
}
}
}
}
}

The API will return a JSON response. One cool thing about GraphQL is that the shape of the returned JSON will match the shape of your query — so you'll know what your response should look like before you even make the query.

There are other cool things (like aliases and fragments) that aren't covered in this guide. A quick intro to the rest of the language can be found in Queries and Mutations on the GraphQL website.

The playground

The GraphQL playground. On the left is the autocomplete menu. On the right is the docs tab.

The playground is your biggest friend. GraphQL is fully typed and self-documenting. This means that if you enter an invalid query, the playground will highlight any mistakes before you run it. It also means that you can hit Ctrl+Space to get suggestions for field or argument names.

For more concrete documentation, you can refer to the "Docs" tab on the right while you input your query. The type of each field is also provided. Here are some examples:

  • String: A nullable string.
  • Page: A nullable page object.
  • User!: A non-null user object.
  • [PageAttribution!]!: A non-null array of non-null page attribution objects.

Query variables

When you're working with GraphQL queries in your code, you may have some parts that depend on user input. Rather than needing to put together a custom query string for each request, you can store the GraphQL query as a string, and provide query variables separately.

Query variables can be used to provide dynamic values for arguments, or toggle whether certain fields are fetched (using @skip and @include directives). On the playground, you can provide variables by opening the "Query Variables" panel on the bottom left of the page.

query Search($query: String!, $noAttributions: Boolean!) {
searchPages(
query: $query
filter: { anyBaseUrl: "http://scp-wiki.wikidot.com" }
) {
url
wikidotInfo {
title
rating
}
attributions @skip(if: $noAttributions) {
type
user {
name
}
}
}
}
JSON
{
"query": "3000",
"noAttributions": false
}

Making requests

Most languages have GraphQL client libraries. You might find one for your language here.

That said, you don't really need one to make a valid GraphQL request. Using any simple request library, you can make a JSON request that contains the GraphQL query string and get a JSON response back.

POST https://api.crom.avn.sh/graphql

User-Agent: My app
Content-Type: application/json

{
  "query": "...",
  "variables": { ... }
}

Implement that request logic however you like in your programming language and HTTP request library of your choice. For example, a basic GraphQL client (using fetch) will look like this:

JavaScript
async function cromApiRequest(query, variables = null) {
// Make a fetch request with the query and (optional) variables.
const response = await fetch("https://api.crom.avn.sh/graphql", {
method: "POST",
headers: new Headers({
"User-Agent": "My test app",
"Content-Type": "application/json"
}),
body: JSON.stringify(variables ? { query, variables } : { query })
});
// If the response status code isn't 200, something is up.
if (!response.ok) {
throw new Error("Got status code: " + response.status);
}
// Parse the response JSON.
const { data, errors } = await response.json();
// If there are errors, throw them.
if (errors && errors.length > 0) {
throw new Error("Got errors: " + JSON.stringify(errors));
}
return data;
}