{"id":16192603,"url":"https://github.com/benawad/graphql-chain","last_synced_at":"2025-03-19T04:30:27.459Z","repository":{"id":57253377,"uuid":"136537724","full_name":"benawad/graphql-chain","owner":"benawad","description":"GraphQL middleware similar to Express's middleware","archived":false,"fork":false,"pushed_at":"2018-06-08T17:41:36.000Z","size":92,"stargazers_count":28,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-28T15:12:31.729Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benawad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-07T22:25:31.000Z","updated_at":"2023-09-22T18:52:13.000Z","dependencies_parsed_at":"2022-08-31T22:11:54.883Z","dependency_job_id":null,"html_url":"https://github.com/benawad/graphql-chain","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benawad%2Fgraphql-chain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benawad%2Fgraphql-chain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benawad%2Fgraphql-chain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benawad%2Fgraphql-chain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benawad","download_url":"https://codeload.github.com/benawad/graphql-chain/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243968376,"owners_count":20376387,"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-10-10T08:10:54.351Z","updated_at":"2025-03-19T04:30:27.147Z","avatar_url":"https://github.com/benawad.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GraphQL Chain\n\nCreate GraphQL middleware that resembles how Express middleware works.\n\n## Install\n\n```\nyarn add graphql-chain\n```\n\n## How to use\n\n### Step 1\n\nCreate middleware\n\n```js\nconst validationMiddleware: MiddlewareResolver = (\n  next,\n  parent,\n  args,\n  context,\n  info\n) =\u003e {\n  if (args.name.length \u003e 10) {\n    throw new Error(\"too long\");\n  }\n\n  return next();\n};\n```\n\nIt has access to all the regular parameters a resolver gets plus a `next` parameter at the beginning which you call and return to call the next middleware or resolver.\n\nYou don't always have to call the next middleware or resolver though. This can be helpful if you want create a caching middleware:\n\n```js\nconst cachingMiddleware: MiddlewareResolver = async (next, _, args) =\u003e {\n  const data = await redis.get(\"hello:cache\");\n  if (data) {\n    // found data in the cache, so return early\n    console.log(\"CACHE HIT\");\n    return data;\n  }\n  // did not find data, so call the next middleware\n  console.log(\"CACHE MISS\");\n  const result = await next();\n  // set cache for next call\n  await redis.set(\"hello:cache\", result);\n  return result;\n};\n```\n\nYou can also change the value of the arguments and then use them later\n\n```js\nconst getUserMiddleware: MiddlewareResolver = async (next, _, __, context) =\u003e {\n  if (validToken(context.authToken)) {\n    // you can add properties to context that you can use later\n    context.user = await getUser(context.authToken);\n  }\n\n  return next();\n};\n```\n\nSo you can then have a middleware that checks the user\n\n```js\nconst authorizationMiddleware: MiddlewareResolver = (next, _, __, context) =\u003e {\n  if (!context.user || !context.user.admin) {\n    throw new Error(\"not authorized\");\n  }\n\n  return next();\n};\n```\n\n### Step 2\n\nChain as many middlewares together as you like\n\n```js\nimport { chain } from \"graphql-chain\";\n\nconst helloMiddleware = chain([\n  getUserMiddleware,\n  authorizationMiddleware,\n  validationMiddleware\n]);\n```\n\n### Step 3\n\nWrap the resolver you want the middleware to run on\n\n```js\nconst resolvers: IResolvers = {\n  Query: {\n    hello: helloMiddleware((_, { name }) =\u003e `Hello ${name || \"World\"}`)\n  }\n};\n```\n\nThe execution sequence will be `getUserMiddleware` -\u003e `authorizationMiddleware` -\u003e `validationMiddleware` -\u003e `hello`\n\nCheckout the `examples` directory for complete examples\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenawad%2Fgraphql-chain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenawad%2Fgraphql-chain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenawad%2Fgraphql-chain/lists"}