{"id":13530278,"url":"https://github.com/apollographql/apollo-fetch","last_synced_at":"2025-10-02T07:30:30.545Z","repository":{"id":45752677,"uuid":"95804445","full_name":"apollographql/apollo-fetch","owner":"apollographql","description":":dog: Lightweight GraphQL client that supports middleware and afterware","archived":true,"fork":false,"pushed_at":"2019-07-03T08:56:47.000Z","size":219,"stargazers_count":568,"open_issues_count":34,"forks_count":32,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-09-10T14:46:14.178Z","etag":null,"topics":["apollo","fetch","graphql","graphql-client","http"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/apollo-fetch","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apollographql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-29T17:51:44.000Z","updated_at":"2025-09-09T18:53:12.000Z","dependencies_parsed_at":"2022-09-12T15:13:58.132Z","dependency_job_id":null,"html_url":"https://github.com/apollographql/apollo-fetch","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/apollographql/apollo-fetch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fapollo-fetch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fapollo-fetch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fapollo-fetch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fapollo-fetch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apollographql","download_url":"https://codeload.github.com/apollographql/apollo-fetch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fapollo-fetch/sbom","scorecard":{"id":203060,"data":{"date":"2025-08-11","repo":{"name":"github.com/apollographql/apollo-fetch","commit":"0a0b8df241960dfa72abf3bd179e9d936265a7da"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.5,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/apollographql/.github/SECURITY.md:1","Info: Found linked content: github.com/apollographql/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/apollographql/.github/SECURITY.md:1","Info: Found text in security policy: github.com/apollographql/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-16T23:09:06.162Z","repository_id":45752677,"created_at":"2025-08-16T23:09:06.163Z","updated_at":"2025-08-16T23:09:06.163Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274574093,"owners_count":25310118,"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","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["apollo","fetch","graphql","graphql-client","http"],"created_at":"2024-08-01T07:00:47.234Z","updated_at":"2025-10-02T07:30:30.308Z","avatar_url":"https://github.com/apollographql.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Uncategorized"],"sub_categories":["Uncategorized"],"readme":"# DEPRECATED\n\nApollo Client 2.0 no longer uses `apollo-fetch` but [`apollo-link`](https://github.com/apollographql/apollo-link) instead. See https://www.apollographql.com/docs/react/2.0-migration.html for an example.\n\n[This module is deprecated and will not receive further updates.](https://github.com/apollographql/apollo-fetch/issues/80)\n\n# apollo-fetch [![npm version](https://badge.fury.io/js/apollo-fetch.svg)](https://badge.fury.io/js/apollo-fetch) [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollostack.com/#slack)\n\n\n`apollo-fetch` is a lightweight client for GraphQL requests that supports middleware and afterware that modify requests and responses.\n\nBy default `apollo-fetch` uses `cross-fetch`, but you have the option of using a custom fetch function.\n\nIf you are interested in contributing, please read the [documentation on repository structure](docs/monorepo.md) and [Contributor Guide](CONTRIBUTING.md).\n\n# Installation\n\n```\nnpm install apollo-fetch --save\n```\n\nTo use `apollo-fetch` in a web browser or mobile app, you'll need a build system capable of loading NPM packages on the client.\nSome common choices include Browserify, Webpack, and Meteor +1.3.\n\n# Usage\n\nTo create a fetch function capable of supporting middleware and afterware, use `createApolloFetch`:\n\n```js\nimport { createApolloFetch } from 'apollo-fetch';\n\nconst uri = 'http://api.githunt.com/graphql';\nconst apolloFetch = createApolloFetch({ uri });\n```\n\nTo execute the fetch function, call `apolloFetch` directly in the following way:\n\n```js\napolloFetch({ query, variables, operationName }) //all apolloFetch arguments are optional\n  .then(result =\u003e {\n    const { data, errors, extensions } = result;\n    //GraphQL errors and extensions are optional\n  })\n  .catch(error =\u003e {\n    //respond to a network error\n  });\n```\n\n### Middleware and Afterware\n\nMiddleware and Afterware are added with `use` and `useAfter` directly to `apolloFetch`:\n\n```js\nconst apolloFetch = createApolloFetch();\n\nconst middleware = ({ request, options }, next) =\u003e { ... next(); };\n\nconst afterware = ({ response, options }, next) =\u003e { ... next(); };\n\napolloFetch.use(middleware);\napolloFetch.useAfter(afterware);\n```\n\nMiddleware and Afterware can be chained together in any order:\n\n```js\nconst apolloFetch = createApolloFetch();\napolloFetch\n  .use(middleware1)\n  .use(middleware2)\n  .useAfter(afterware1)\n  .useAfter(afterware2)\n  .use(middleware3);\n```\n\n### Custom Fetch\n\nFor mocking and other fetching behavior, you may pass a fetch into `createApolloFetch`:\n\n```js\nconst customFetch = createFileFetch();\nconst apolloFetch = createApolloFetch({ customFetch });\n```\n\n### Custom GraphQL to Fetch Translation\n\nTo modify how GraphQL requests are incorporated in the fetch options, you may pass a transformation function into `createApolloFetch`.\n`apollo-fetch` exports `constructDefaultOptions` to allow conditional creation of the fetch options.\nThese transformations can be useful for servers that have different formatting for batches or other extra capabilities.\n\n```js\n//requestOrRequests: GraphQLRequest | GraphQLRequest[]\n//options: RequestInit\nconst constructOptions = (requestOrRequests, options) =\u003e {\n  return {\n    ...options,\n    body: JSON.stringify(requestOrRequests),\n  }\n};\nconst apolloFetch = createApolloFetch({ constructOptions });\n\n//simplified usage inside apolloFetch\nfetch(uri, constructOptions(requestOrRequests, options)); //requestOrRequests and options are the results from middleware\n```\n\n### Batched Requests\n\nBatched requests are also supported by the fetch function returned by `createApolloFetch`, please refer the [batched request guide](docs/batch.md) for a complete description.\n\n# Examples\n\n### Simple GraphQL Query\n\n```js\nimport { createApolloFetch } from 'apollo-fetch';\n\nconst uri = 'http://api.githunt.com/graphql';\n\nconst query = `\n  query CurrentUser {\n    currentUser {\n      login,\n    }\n  }\n`\nconst apolloFetch = createApolloFetch({ uri });\n\napolloFetch({ query }).then(...).catch(...);\n```\n\n### Simple GraphQL Mutation with Variables\n\n```js\nimport { createApolloFetch } from 'apollo-fetch';\n\nconst uri = 'http://api.githunt.com/graphql';\n\nconst query = `\n  mutation SubmitRepo ($repoFullName: String!) {\n    submitRepository (repoFullName: $repoFullName) {\n      id,\n      score,\n    }\n  }\n`;\n\nconst variables = {\n  repoFullName: 'apollographql/apollo-fetch',\n};\n\nconst apolloFetch = createApolloFetch({ uri });\n\napolloFetch({ query, variables }).then(...).catch(...);\n```\n\n### Middleware\n\nA GraphQL mutation with authentication middleware.\nMiddleware has access to the GraphQL query and the options passed to fetch.\n\n```js\nimport { createApolloFetch } from 'apollo-fetch';\n\nconst uri = 'http://api.githunt.com/graphql';\n\nconst apolloFetch = createApolloFetch({ uri });\n\napolloFetch.use(({ request, options }, next) =\u003e {\n  if (!options.headers) {\n    options.headers = {};  // Create the headers object if needed.\n  }\n  options.headers['authorization'] = 'created token';\n\n  next();\n});\n\napolloFetch(...).then(...).catch(...);\n```\n\n### Afterware\n\nAfterware to check the response status and logout on a 401.\nThe afterware has access to the raw reponse always and parsed response when the data is proper JSON.\n\n```js\nimport { createApolloFetch } from 'apollo-fetch';\n\nconst uri = 'http://api.githunt.com/graphql';\n\nconst apolloFetch = createApolloFetch({ uri });\n\napolloFetch.useAfter(({ response }, next) =\u003e {\n  if (response.status === 401) {\n    logout();\n  }\n  next();\n});\n\napolloFetch(...).then(...).catch(...);\n```\n\n### Mocking a Fetch Call\n\nThis example uses a custom fetch to mock an unauthorized(401) request with a non-standard response body.\n`apollo-fetch` replaces the call to `fetch` with `customFetch`, which both follow the standard [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).\n\n```js\nconst customFetch = () =\u003e new Promise((resolve, reject) =\u003e {\n  const init = {\n    status: 401,\n    statusText: 'Unauthorized',\n  };\n  const body = JSON.stringify({\n    data: {\n      user: null,\n    }\n  });\n  resolve(new Response(body, init));\n}\n\nconst apolloFetch = createApolloFetch({ customFetch });\n```\n\n### Error Handling\n\nAll responses are passed to the afterware regardless of the http status code.\nNetwork errors, `FetchError`, are thrown after the afterware is run and if no parsed response is received.\n\nThis example shows an afterware that can receive a 401 with an unparsable response and return a valid `FetchResult`.\nCurrently all other status codes that have an uparsable response would throw an error.\nThis means if a server returns a parsable GraphQL result on a 403 for example, the result would be passed to `then` without error.\nErrors in Middleware and Afterware are propagated without modification.\n\n```js\nimport { createApolloFetch } from 'apollo-fetch';\n\nconst uri = 'http://api.githunt.com/graphql';\n\nconst apolloFetch = createApolloFetch({ uri });\n\napolloFetch.useAfter(({ response }, next) =\u003e {\n  //response.raw will be a non-null string\n  //response.parsed may be a FetchResult or undefined\n\n  if (response.status === 401 \u0026\u0026 !response.parsed) {\n    //set parsed response to valid FetchResult\n    response.parsed = {\n      data: { user: null },\n    };\n  }\n\n  next();\n});\n\n//Here catch() receives all responses with unparsable data\napolloFetch(...).then(...).catch(...);\n```\n\n### Apollo Integration\n\n`apollo-fetch` is the first part of [Apollo Client's](https://github.com/apollographql/apollo-client) future network stack.\nIf you would like to try it out today,\nyou may replace the network interface with the following:\n\n```js\nimport ApolloClient from 'apollo-client';\nimport { createApolloFetch } from 'apollo-fetch';\nimport { print } from 'graphql/language/printer';\n\nconst uri = 'http://api.githunt.com/graphql';\n\nconst apolloFetch = createApolloFetch({ uri });\n\nconst networkInterface = {\n  query: (req) =\u003e apolloFetch({...req, query: print(req.query)}),\n};\n\nconst client = new ApolloClient({\n  networkInterface,\n});\n```\n\n# API\n\n`createApolloFetch` is a factory for `ApolloFetch`, a fetch function with middleware and afterware capabilities.\n[`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) and [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request) follow the MDN standard fetch API.\n\n```js\ncreateApolloFetch(options: FetchOptions): ApolloFetch\n\nFetchOptions {\n  uri?: string;\n  customFetch?: (request: RequestInfo, init: RequestInit) =\u003e Promise\u003cResponse\u003e;\n  constructOptions?: (requestOrRequests: GraphQLRequest | GraphQLRequest[], options: RequestInit) =\u003e RequestInit;\n}\n/*\n * defaults:\n * uri = '/graphql'\n * customFetch = fetch from cross-fetch\n * constructOptions = constructDefaultOptions(exported from apollo-fetch)\n */\n```\n\n`ApolloFetch`, a fetch function with middleware, afterware, and batched request capabilities.\nFor information on batch usage, see the [batched request documentation](docs/batch.md).\n\n```js\nApolloFetch {\n  (operation: GraphQLRequest): Promise\u003cFetchResult\u003e;\n  use: (middlewares: MiddlewareInterface) =\u003e ApolloFetch;\n  useAfter: (afterwares: AfterwareInterface) =\u003e ApolloFetch;\n\n  //Batched requests are described in the docs/batch.md\n  (operation: GraphQLRequest[]): Promise\u003cFetchResult[]\u003e;\n  batchUse: (middlewares: BatchMiddlewareInterface) =\u003e ApolloFetch;\n  batchUseAfter: (afterwares: BatchAfterwareInterface) =\u003e ApolloFetch;\n}\n```\n\n`GraphQLRequest` is the argument to an `ApolloFetch` call.\n`query` is optional to support persistent queries based on only an `operationName`.\n\n```js\nGraphQLRequest {\n  query?: string;\n  variables?: object;\n  operationName?: string;\n}\n```\n\n`FetchResult` is the return value of an `ApolloFetch` call\n\n```js\nFetchResult {\n  data: any;\n  errors?: any;\n  extensions?: any;\n}\n```\n\nMiddleware used by `ApolloFetch`\n\n```js\nMiddlewareInterface: (request: RequestAndOptions, next: Function) =\u003e void\n\nRequestAndOptions {\n  request: GraphQLRequest;\n  options: RequestInit;\n}\n```\n\nAfterware used by `ApolloFetch`\n\n```js\nAfterwareInterface: (response: ResponseAndOptions, next: Function) =\u003e void\n\nResponseAndOptions {\n  response: ParsedResponse;\n  options: RequestInit;\n}\n```\n\n`ParsedResponse` adds `raw` (the body from the `.text()` call) to the fetch result, and `parsed` (the parsed JSON from `raw`) to the fetch's standard [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).\n\n```js\nParsedResponse extends Response {\n  raw: string;\n  parsed?: any;\n}\n```\n\nA `FetchError` is returned from a failed call to `ApolloFetch`\nis standard [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) that contains the response and a possible parse error.\nThe `parseError` is generated when the raw response is not valid JSON (when `JSON.parse()` throws) and the Afterware does not add an object to the response's `parsed` property.\nErrors in Middleware and Afterware are propagated without modification.\n\n```js\nFetchError extends Error {\n  response: ParsedResponse;\n  parseError?: Error;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapollographql%2Fapollo-fetch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapollographql%2Fapollo-fetch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapollographql%2Fapollo-fetch/lists"}