{"id":15130263,"url":"https://github.com/input-output-hk/graphql-request","last_synced_at":"2025-09-28T19:31:35.285Z","repository":{"id":44536193,"uuid":"455100502","full_name":"input-output-hk/graphql-request","owner":"input-output-hk","description":"Minimal GraphQL client supporting Node and browsers for scripts or simple apps","archived":false,"fork":true,"pushed_at":"2022-03-17T09:15:36.000Z","size":1072,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-15T14:15:27.908Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"graffle-js/graffle","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/input-output-hk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-03T09:21:54.000Z","updated_at":"2024-10-16T21:57:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/input-output-hk/graphql-request","commit_stats":null,"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/input-output-hk%2Fgraphql-request","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/input-output-hk%2Fgraphql-request/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/input-output-hk%2Fgraphql-request/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/input-output-hk%2Fgraphql-request/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/input-output-hk","download_url":"https://codeload.github.com/input-output-hk/graphql-request/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234555823,"owners_count":18851853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-26T02:43:21.467Z","updated_at":"2025-09-28T19:31:29.967Z","avatar_url":"https://github.com/input-output-hk.png","language":"TypeScript","readme":"# graphql-request\n\nMinimal GraphQL client supporting Node and browsers for scripts or simple apps\n\n![GitHub Action](https://github.com/prisma-labs/graphql-request/workflows/trunk/badge.svg) [![npm version](https://badge.fury.io/js/graphql-request.svg)](https://badge.fury.io/js/graphql-request)\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n\n- [Features](#features)\n- [Install](#install)\n- [Quickstart](#quickstart)\n- [Usage](#usage)\n- [Node Version Support](#node-version-support)\n- [Community](#community)\n    - [GraphQL Code Generator's GraphQL-Request TypeScript Plugin](#graphql-code-generators-graphql-request-typescript-plugin)\n- [Examples](#examples)\n  - [Authentication via HTTP header](#authentication-via-http-header)\n    - [Incrementally setting headers](#incrementally-setting-headers)\n  - [Passing Headers in each request](#passing-headers-in-each-request)\n  - [Passing more options to `fetch`](#passing-more-options-to-fetch)\n    - [Custom JSON serializer](#custom-json-serializer)\n  - [Using GraphQL Document variables](#using-graphql-document-variables)\n  - [GraphQL Mutations](#graphql-mutations)\n  - [Error handling](#error-handling)\n  - [Using `require` instead of `import`](#using-require-instead-of-import)\n  - [Cookie support for `node`](#cookie-support-for-node)\n  - [Using a custom `fetch` method](#using-a-custom-fetch-method)\n  - [Receiving a raw response](#receiving-a-raw-response)\n  - [File Upload](#file-upload)\n    - [Browser](#browser)\n    - [Node](#node)\n  - [Batching](#batching)\n  - [Cancellation](#cancellation)\n- [FAQ](#faq)\n    - [Why do I have to install `graphql`?](#why-do-i-have-to-install-graphql)\n    - [Do I need to wrap my GraphQL documents inside the `gql` template exported by `graphql-request`?](#do-i-need-to-wrap-my-graphql-documents-inside-the-gql-template-exported-by-graphql-request)\n    - [What's the difference between `graphql-request`, Apollo and Relay?](#whats-the-difference-between-graphql-request-apollo-and-relay)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Features\n\n- Most **simple \u0026 lightweight** GraphQL client\n- Promise-based API (works with `async` / `await`)\n- TypeScript support\n- Isomorphic (works with Node / browsers)\n\n## Install\n\n```sh\nnpm add graphql-request graphql\n```\n\n## Quickstart\n\nSend a GraphQL query with a single line of code. ▶️ [Try it out](https://runkit.com/593130bdfad7120012472003/593130bdfad7120012472004).\n\n```js\nimport { request, gql } from 'graphql-request'\n\nconst query = gql`\n  {\n    Movie(title: \"Inception\") {\n      releaseDate\n      actors {\n        name\n      }\n    }\n  }\n`\n\nrequest('https://api.graph.cool/simple/v1/movies', query).then((data) =\u003e console.log(data))\n```\n\n## Usage\n\n```js\nimport { request, GraphQLClient } from 'graphql-request'\n\n// Run GraphQL queries/mutations using a static function\nrequest(endpoint, query, variables).then((data) =\u003e console.log(data))\n\n// ... or create a GraphQL client instance to send requests\nconst client = new GraphQLClient(endpoint, { headers: {} })\nclient.request(query, variables).then((data) =\u003e console.log(data))\n```\n\nYou can also use the single argument function variant:\n\n```js\nrequest({\n  url: endpoint,\n  document: query,\n  variables: variables,\n  requestHeaders: headers,\n}).then((data) =\u003e console.log(data))\n```\n\n## Node Version Support\n\nWe only officially support [LTS Node versions](https://github.com/nodejs/Release#release-schedule). We also make an effort to support two additional versions:\n\n1. The latest even Node version if it is not LTS already.\n2. The odd Node version directly following the latest even version.\n\nYou are free to try using other versions of Node (e.g. `13.x`) with `graphql-request` but at your own risk.\n\n## Community\n\n#### GraphQL Code Generator's GraphQL-Request TypeScript Plugin\n\nA [GraphQL-Codegen plugin](https://graphql-code-generator.com/docs/plugins/typescript-graphql-request) that generates a `graphql-request` ready-to-use SDK, which is fully-typed.\n\n## Examples\n\n### Authentication via HTTP header\n\n```js\nimport { GraphQLClient, gql } from 'graphql-request'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const graphQLClient = new GraphQLClient(endpoint, {\n    headers: {\n      authorization: 'Bearer MY_TOKEN',\n    },\n  })\n\n  const query = gql`\n    {\n      Movie(title: \"Inception\") {\n        releaseDate\n        actors {\n          name\n        }\n      }\n    }\n  `\n\n  const data = await graphQLClient.request(query)\n  console.log(JSON.stringify(data, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n[TypeScript Source](examples/authentication-via-http-header.ts)\n\n#### Incrementally setting headers\n\nIf you want to set headers after the GraphQLClient has been initialised, you can use the `setHeader()` or `setHeaders()` functions.\n\n```js\nimport { GraphQLClient } from 'graphql-request'\n\nconst client = new GraphQLClient(endpoint)\n\n// Set a single header\nclient.setHeader('authorization', 'Bearer MY_TOKEN')\n\n// Override all existing headers\nclient.setHeaders({\n  authorization: 'Bearer MY_TOKEN',\n  anotherheader: 'header_value'\n})\n```\n\n#### Set endpoint\n\nIf you want to change the endpoint after the GraphQLClient has been initialised, you can use the `setEndpoint()` function.\n\n```js\nimport { GraphQLClient } from 'graphql-request'\n\nconst client = new GraphQLClient(endpoint)\n\nclient.setEndpoint(newEndpoint)\n\n```\n\n#### passing-headers-in-each-request\n\nIt is possible to pass custom headers for each request. `request()` and `rawRequest()` accept a header object as the third parameter\n\n\n```js\nimport { GraphQLClient } from 'graphql-request'\n\nconst client = new GraphQLClient(endpoint)\n\nconst query = gql`\n  query getMovie($title: String!) {\n    Movie(title: $title) {\n      releaseDate\n      actors {\n        name\n      }\n    }\n  }\n`\n\nconst variables = {\n  title: 'Inception',\n}\n\nconst requestHeaders = {\n  authorization: 'Bearer MY_TOKEN'\n}\n\n// Overrides the clients headers with the passed values\nconst data = await client.request(query, variables, requestHeaders)\n```\n\n### Passing more options to `fetch`\n\n```js\nimport { GraphQLClient, gql } from 'graphql-request'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const graphQLClient = new GraphQLClient(endpoint, {\n    credentials: 'include',\n    mode: 'cors',\n  })\n\n  const query = gql`\n    {\n      Movie(title: \"Inception\") {\n        releaseDate\n        actors {\n          name\n        }\n      }\n    }\n  `\n\n  const data = await graphQLClient.request(query)\n  console.log(JSON.stringify(data, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n[TypeScript Source](examples/passing-more-options-to-fetch.ts)\n\n### Custom JSON serializer\n\nIf you want to use non-standard JSON types, you can use your own JSON serializer to replace `JSON.parse`/`JSON.stringify` used by the `GraphQLClient`.\n\nAn original use case for this feature is `BigInt` support:\n\n```js\nimport JSONbig from 'json-bigint'\nimport { GraphQLClient, gql } from 'graphql-request'\n\nasync function main() {\n  const jsonSerializer = JSONbig({ useNativeBigInt: true })\n  const graphQLClient = new GraphQLClient(endpoint, { jsonSerializer })\n  const data = await graphQLClient.request(\n    gql`\n      {\n        someBigInt\n      }\n    `\n  )\n  console.log(typeof data.someBigInt) // if \u003eMAX_SAFE_INTEGER then 'bigint' else 'number'\n}\n```\n\n### Using GraphQL Document variables\n\n```js\nimport { request, gql } from 'graphql-request'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const query = gql`\n    query getMovie($title: String!) {\n      Movie(title: $title) {\n        releaseDate\n        actors {\n          name\n        }\n      }\n    }\n  `\n\n  const variables = {\n    title: 'Inception',\n  }\n\n  const data = await request(endpoint, query, variables)\n  console.log(JSON.stringify(data, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n### GraphQL Mutations\n\n```js\nimport { GraphQLClient, gql } from 'graphql-request'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const graphQLClient = new GraphQLClient(endpoint, {\n    headers: {\n      authorization: 'Bearer MY_TOKEN',\n    },\n  })\n\n  const mutation = gql`\n    mutation AddMovie($title: String!, $releaseDate: Int!) {\n      insert_movies_one(object: { title: $title, releaseDate: $releaseDate }) {\n        title\n        releaseDate\n      }\n    }\n  `\n\n  const variables = {\n    title: 'Inception',\n    releaseDate: 2010,\n  }\n  const data = await graphQLClient.request(mutation, variables)\n\n  console.log(JSON.stringify(data, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n[TypeScript Source](examples/using-variables.ts)\n\n### Error handling\n\n```js\nimport { request, gql } from 'graphql-request'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const query = gql`\n    {\n      Movie(title: \"Inception\") {\n        releaseDate\n        actors {\n          fullname # \"Cannot query field 'fullname' on type 'Actor'. Did you mean 'name'?\"\n        }\n      }\n    }\n  `\n\n  try {\n    const data = await request(endpoint, query)\n    console.log(JSON.stringify(data, undefined, 2))\n  } catch (error) {\n    console.error(JSON.stringify(error, undefined, 2))\n    process.exit(1)\n  }\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n[TypeScript Source](examples/error-handling.ts)\n\n### Using `require` instead of `import`\n\n```js\nconst { request, gql } = require('graphql-request')\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const query = gql`\n    {\n      Movie(title: \"Inception\") {\n        releaseDate\n        actors {\n          name\n        }\n      }\n    }\n  `\n\n  const data = await request(endpoint, query)\n  console.log(JSON.stringify(data, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n### Cookie support for `node`\n\n```sh\nnpm install fetch-cookie\n```\n\n```js\nrequire('fetch-cookie/node-fetch')(require('node-fetch'))\n\nimport { GraphQLClient, gql } from 'graphql-request'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const graphQLClient = new GraphQLClient(endpoint, {\n    headers: {\n      authorization: 'Bearer MY_TOKEN',\n    },\n  })\n\n  const query = gql`\n    {\n      Movie(title: \"Inception\") {\n        releaseDate\n        actors {\n          name\n        }\n      }\n    }\n  `\n\n  const data = await graphQLClient.rawRequest(query)\n  console.log(JSON.stringify(data, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n[TypeScript Source](examples/cookie-support-for-node.ts)\n\n### Using a custom `fetch` method\n\n```sh\nnpm install fetch-cookie\n```\n\n```js\nimport { GraphQLClient, gql } from 'graphql-request'\nimport crossFetch from 'cross-fetch'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  // a cookie jar scoped to the client object\n  const fetch = require('fetch-cookie')(crossFetch)\n  const graphQLClient = new GraphQLClient(endpoint, { fetch })\n\n  const query = gql`\n    {\n      Movie(title: \"Inception\") {\n        releaseDate\n        actors {\n          name\n        }\n      }\n    }\n  `\n\n  const data = await graphQLClient.rawRequest(query)\n  console.log(JSON.stringify(data, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n### Receiving a raw response\n\nThe `request` method will return the `data` or `errors` key from the response.\nIf you need to access the `extensions` key you can use the `rawRequest` method:\n\n```js\nimport { rawRequest, gql } from 'graphql-request'\n\nasync function main() {\n  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'\n\n  const query = gql`\n    {\n      Movie(title: \"Inception\") {\n        releaseDate\n        actors {\n          name\n        }\n      }\n    }\n  `\n\n  const { data, errors, extensions, headers, status } = await rawRequest(endpoint, query)\n  console.log(JSON.stringify({ data, errors, extensions, headers, status }, undefined, 2))\n}\n\nmain().catch((error) =\u003e console.error(error))\n```\n\n### File Upload\n\n#### Browser\n\n```js\nimport { request } from 'graphql-request'\n\nconst UploadUserAvatar = gql`\n  mutation uploadUserAvatar($userId: Int!, $file: Upload!) {\n    updateUser(id: $userId, input: { avatar: $file })\n  }\n`\n\nrequest('/api/graphql', UploadUserAvatar, {\n  userId: 1,\n  file: document.querySelector('input#avatar').files[0],\n})\n```\n\n#### Node\n\n```js\nimport { createReadStream } from 'fs'\nimport { request } from 'graphql-request'\n\nconst UploadUserAvatar = gql`\n  mutation uploadUserAvatar($userId: Int!, $file: Upload!) {\n    updateUser(id: $userId, input: { avatar: $file })\n  }\n`\n\nrequest('/api/graphql', UploadUserAvatar, {\n  userId: 1,\n  file: createReadStream('./avatar.img'),\n})\n```\n\n[TypeScript Source](examples/receiving-a-raw-response.ts)\n\n\n### Batching\n\nIt is possible with `graphql-request` to use [batching](https://github.com/graphql/graphql-over-http/blob/main/rfcs/Batching.md) via the `batchRequests()` function. Example available at [examples/batching-requests.ts](examples/batching-requests.ts)\n\n```ts\nimport { batchRequests } from 'graphql-request';\n\n(async function () {\n  const endpoint = 'https://api.spacex.land/graphql/';\n\n  const query1 = /* GraphQL */ `\n    query ($id: ID!) {\n      capsule(id: $id) {\n        id\n        landings\n      }\n    }\n  `;\n\n  const query2 = /* GraphQL */ `\n    {\n      rockets(limit: 10) {\n        active\n      }\n    }\n  `;\n\n  const data = await batchRequests(endpoint, [\n    { document: query1, variables: { id: 'C105' } },\n    { document: query2 },\n  ])\n  console.log(JSON.stringify(data, undefined, 2))\n})().catch((error) =\u003e console.error(error))\n```\n\n### Cancellation\n\nIt is possible to cancel a request using an `AbortController` signal.\n\nYou can define the `signal` in the `GraphQLClient` constructor:\n\n```ts\n  const abortController = new AbortController()\n\n  const client = new GraphQLClient(endpoint, { signal: abortController.signal })\n  client.request(query)\n\n  abortController.abort()\n```\n\nYou can also set the signal per request (this will override an existing GraphQLClient signal):\n\n```ts\n  const abortController = new AbortController()\n\n  const client = new GraphQLClient(endpoint)\n  client.request({ document: query, signal: abortController.signal })\n\n  abortController.abort()\n```\n\nIn Node environment, `AbortController` is supported since version v14.17.0.\nFor Node.js v12 you can use [abort-controller](https://github.com/mysticatea/abort-controller) polyfill.\n\n````\n import 'abort-controller/polyfill'\n\n const abortController = new AbortController()\n````\n\n## FAQ\n\n#### Why do I have to install `graphql`?\n\n`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](https://github.com/prisma-labs/graphql-request/pull/183#discussion_r464453076). 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.\n\n#### Do I need to wrap my GraphQL documents inside the `gql` template exported by `graphql-request`?\n\nNo. 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.\n\n#### What's the difference between `graphql-request`, Apollo and Relay?\n\n`graphql-request` is the most minimal and simplest to use GraphQL client. It's perfect for small scripts or simple apps.\n\nCompared 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.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finput-output-hk%2Fgraphql-request","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finput-output-hk%2Fgraphql-request","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finput-output-hk%2Fgraphql-request/lists"}