graphql-request
Minimal GraphQL client supporting Node and browsers for scripts or simple apps
- Features
- Install
- Quickstart
- Usage
- Node Version Support
- Community
- Examples
- FAQ
Features
- Most simple & lightweight GraphQL client
- Promise-based API (works with
async
/await
) - TypeScript support
- Isomorphic (works with Node / browsers)
Install
npm add graphql-request graphql
Quickstart
Send a GraphQL query with a single line of code.
import { request, gql } from 'graphql-request'
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
request('https://api.graph.cool/simple/v1/movies', query).then((data) => console.log(data))
Usage
import { request, GraphQLClient } from 'graphql-request'
// Run GraphQL queries/mutations using a static function
request(endpoint, query, variables).then((data) => console.log(data))
// ... or create a GraphQL client instance to send requests
const client = new GraphQLClient(endpoint, { headers: {} })
client.request(query, variables).then((data) => console.log(data))
Node Version Support
We only officially support LTS Node versions. We also make an effort to support two additional versions:
- The latest even Node version if it is not LTS already.
- The odd Node version directly following the latest even version.
You are free to try using other versions of Node (e.g. 13.x
) with graphql-request
but at your own risk.
Community
GraphQL Code Generator's GraphQL-Request TypeScript Plugin
A GraphQL-Codegen plugin that generates a graphql-request
ready-to-use SDK, which is fully-typed.
Examples
Authentication via HTTP header
import { GraphQLClient, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const graphQLClient = new GraphQLClient(endpoint, {
headers: {
authorization: 'Bearer MY_TOKEN',
},
})
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
const data = await graphQLClient.request(query)
console.log(JSON.stringify(data, undefined, 2))
}
main().catch((error) => console.error(error))
Incrementally setting headers
If you want to set headers after the GraphQLClient has been initialised, you can use the setHeader()
or setHeaders()
functions.
import { GraphQLClient } from 'graphql-request'
const client = new GraphQLClient(endpoint)
// Set a single header
client.setHeader('authorization', 'Bearer MY_TOKEN')
// Override all existing headers
client.setHeaders({
authorization: 'Bearer MY_TOKEN',
anotherheader: 'header_value'
})
Set endpoint
If you want to change the endpoint after the GraphQLClient has been initialised, you can use the setEndpoint()
function.
import { GraphQLClient } from 'graphql-request'
const client = new GraphQLClient(endpoint)
client.setEndpoint(newEndpoint)
passing-headers-in-each-request
It is possible to pass custom headers for each request. request()
and rawRequest()
accept a header object as the third parameter
import { GraphQLClient } from 'graphql-request'
const client = new GraphQLClient(endpoint)
const query = gql`
query getMovie($title: String!) {
Movie(title: $title) {
releaseDate
actors {
name
}
}
}
`
const variables = {
title: 'Inception',
}
const requestHeaders = {
authorization: 'Bearer MY_TOKEN'
}
// Overrides the clients headers with the passed values
const data = await client.request(query, variables, requestHeaders)
fetch
Passing more options to import { GraphQLClient, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const graphQLClient = new GraphQLClient(endpoint, {
credentials: 'include',
mode: 'cors',
})
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
const data = await graphQLClient.request(query)
console.log(JSON.stringify(data, undefined, 2))
}
main().catch((error) => console.error(error))
Using GraphQL Document variables
import { request, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const query = gql`
query getMovie($title: String!) {
Movie(title: $title) {
releaseDate
actors {
name
}
}
}
`
const variables = {
title: 'Inception',
}
const data = await request(endpoint, query, variables)
console.log(JSON.stringify(data, undefined, 2))
}
main().catch((error) => console.error(error))
GraphQL Mutations
import { GraphQLClient, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const graphQLClient = new GraphQLClient(endpoint, {
headers: {
authorization: 'Bearer MY_TOKEN',
},
})
const mutation = gql`
mutation AddMovie($title: String!, $releaseDate: Int!) {
insert_movies_one(object: { title: $title, releaseDate: $releaseDate }) {
title
releaseDate
}
}
`
const variables = {
title: 'Inception',
releaseDate: 2010,
}
const data = await graphQLClient.request(mutation, variables)
console.log(JSON.stringify(data, undefined, 2))
}
main().catch((error) => console.error(error))
Error handling
import { request, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
fullname # "Cannot query field 'fullname' on type 'Actor'. Did you mean 'name'?"
}
}
}
`
try {
const data = await request(endpoint, query)
console.log(JSON.stringify(data, undefined, 2))
} catch (error) {
console.error(JSON.stringify(error, undefined, 2))
process.exit(1)
}
}
main().catch((error) => console.error(error))
require
instead of import
Using const { request, gql } = require('graphql-request')
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
const data = await request(endpoint, query)
console.log(JSON.stringify(data, undefined, 2))
}
main().catch((error) => console.error(error))
node
Cookie support for npm install fetch-cookie
require('fetch-cookie/node-fetch')(require('node-fetch'))
import { GraphQLClient, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const graphQLClient = new GraphQLClient(endpoint, {
headers: {
authorization: 'Bearer MY_TOKEN',
},
})
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
const data = await graphQLClient.rawRequest(query)
console.log(JSON.stringify(data, undefined, 2))
}
main().catch((error) => console.error(error))
fetch
method
Using a custom npm install fetch-cookie
import { GraphQLClient, gql } from 'graphql-request'
import crossFetch from 'cross-fetch'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
// a cookie jar scoped to the client object
const fetch = require('fetch-cookie')(crossFetch)
const graphQLClient = new GraphQLClient(endpoint, { fetch })
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
const data = await graphQLClient.rawRequest(query)
console.log(JSON.stringify(data, undefined, 2))
}
main().catch((error) => console.error(error))
Receiving a raw response
The request
method will return the data
or errors
key from the response.
If you need to access the extensions
key you can use the rawRequest
method:
import { rawRequest, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'
const query = gql`
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
const { data, errors, extensions, headers, status } = await rawRequest(endpoint, query)
console.log(JSON.stringify({ data, errors, extensions, headers, status }, undefined, 2))
}
main().catch((error) => console.error(error))
File Upload
Browser
import { request } from 'graphql-request'
const UploadUserAvatar = gql`
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file })
}
`
request('/api/graphql', UploadUserAvatar, {
userId: 1,
file: document.querySelector('input#avatar').files[0],
})
Node
import { createReadStream } from 'fs'
import { request } from 'graphql-request'
const UploadUserAvatar = gql`
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file })
}
`
request('/api/graphql', UploadUserAvatar, {
userId: 1,
file: createReadStream('./avatar.img'),
})
Batching
It is possible with graphql-request
to use batching via the batchRequests()
function. Example available at examples/batching-requests.ts
import { batchRequests } from 'graphql-request';
(async function () {
const endpoint = 'https://api.spacex.land/graphql/';
const query1 = /* GraphQL */ `
query ($id: ID!) {
capsule(id: $id) {
id
landings
}
}
`;
const query2 = /* GraphQL */ `
{
rockets(limit: 10) {
active
}
}
`;
const data = await batchRequests(endpoint, [
{ document: query1, variables: { id: 'C105' } },
{ document: query2 },
])
console.log(JSON.stringify(data, undefined, 2))
})().catch((error) => console.error(error))
FAQ
graphql
?
Why do I have to install graphql-request
uses a TypeScript type from the graphql
package such that if you are using TypeScript to build your project and you are using graphql-request
but don't have graphql
installed TypeScript build will fail. Details here. If you are a JS user then you do not technically need to install graphql
. However if you use an IDE that picks up TS types even for JS (like VSCode) then its still in your interest to install graphql
so that you can benefit from enhanced type safety during development.
gql
template exported by graphql-request
?
Do I need to wrap my GraphQL documents inside the No. It is there for convenience so that you can get the tooling support like prettier formatting and IDE syntax highlighting. You can use gql
from graphql-tag
if you need it for some reason too.
graphql-request
, Apollo and Relay?
What's the difference between graphql-request
is the most minimal and simplest to use GraphQL client. It's perfect for small scripts or simple apps.
Compared to GraphQL clients like Apollo or Relay, graphql-request
doesn't have a built-in cache and has no integrations for frontend frameworks. The goal is to keep the package and API as minimal as possible.