{"_id":"graphql-depth-limit","_rev":"2022493","name":"graphql-depth-limit","description":"Limit the complexity of your GraphQL queries based on depth.","dist-tags":{"latest":"1.1.0"},"maintainers":[{"name":"npm:acarl005","email":""}],"time":{"modified":"2021-12-20T23:07:10.000Z","created":"2017-08-09T02:01:45.459Z","1.1.0":"2017-08-09T22:23:53.743Z","1.0.0":"2017-08-09T02:01:45.459Z"},"users":{},"author":{"name":"Andrew Carlson","email":"acarl005@g.ucla.edu"},"repository":{"type":"git","url":"git+https://github.com/stems/graphql-depth-limit.git"},"versions":{"1.1.0":{"name":"graphql-depth-limit","version":"1.1.0","description":"Limit the complexity of your GraphQL queries based on depth.","engines":{"node":">=6.0.0"},"main":"index.js","scripts":{"docs":"sed -n '/Documentation/q;p' README.md > README.bak.md; echo '## Documentation' >> README.bak.md; jsdoc2md --heading-depth 3 index.js >> README.bak.md && mv -f README.bak.md README.md","lint":"eslint index.js","test":"ava test.js"},"ava":{"verbose":true},"files":["index.js"],"repository":{"type":"git","url":"git+https://github.com/stems/graphql-depth-limit.git"},"keywords":["graphql","complexity","query","depth","limit"],"author":{"name":"Andrew Carlson","email":"acarl005@g.ucla.edu"},"license":"MIT","bugs":{"url":"https://github.com/stems/graphql-depth-limit/issues"},"homepage":"https://github.com/stems/graphql-depth-limit#readme","peerDependencies":{"graphql":"*"},"devDependencies":{"ava":"^0.21.0","eslint":"^4.4.1","eslint-config-airbnb-base":"^11.3.1","graphql":"^0.10.5","jsdoc-to-markdown":"^3.0.0"},"dependencies":{"arrify":"^1.0.1"},"gitHead":"1224c9229aeea548015fc46074437e40061b320c","_id":"graphql-depth-limit@1.1.0","_npmVersion":"5.3.0","_nodeVersion":"8.1.3","_npmUser":{"name":"acarl005","email":"acarl005@g.ucla.edu"},"dist":{"shasum":"59fe6b2acea0ab30ee7344f4c75df39cc18244e8","size":4548,"noattachment":false,"key":"/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/graphql-depth-limit/download/graphql-depth-limit-1.1.0.tgz"},"maintainers":[{"name":"npm:acarl005","email":""}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql-depth-limit-1.1.0.tgz_1502317433541_0.4218081545550376"},"directories":{},"publish_time":1502317433743,"_hasShrinkwrap":false,"_cnpm_publish_time":1502317433743},"1.0.0":{"name":"graphql-depth-limit","version":"1.0.0","description":"Limit the complexity of your GraphQL queries based on depth.","engines":{"node":">=6.0.0"},"main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/stems/graphql-depth-limit.git"},"keywords":["graphql","complexity","query","depth","limit"],"author":{"name":"Andrew Carlson","email":"acarl005@g.ucla.edu"},"license":"MIT","bugs":{"url":"https://github.com/stems/graphql-depth-limit/issues"},"homepage":"https://github.com/stems/graphql-depth-limit#readme","peerDependencies":{"graphql":"*"},"gitHead":"6d9bc6a445d324aad5e553a2eb003dbd0a510f24","_id":"graphql-depth-limit@1.0.0","_npmVersion":"5.3.0","_nodeVersion":"8.1.3","_npmUser":{"name":"acarl005","email":"acarl005@g.ucla.edu"},"dist":{"shasum":"1534c0386a58133254500fad028b12aee87479d0","size":3484,"noattachment":false,"key":"/graphql-depth-limit/-/graphql-depth-limit-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/graphql-depth-limit/download/graphql-depth-limit-1.0.0.tgz"},"maintainers":[{"name":"npm:acarl005","email":""}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql-depth-limit-1.0.0.tgz_1502244105278_0.8910202339757234"},"directories":{},"publish_time":1502244105459,"_hasShrinkwrap":false,"_cnpm_publish_time":1502244105459}},"readme":"GraphQL Depth Limit\n===================\n\nDead-simple defense against unbounded GraphQL queries. Limit the complexity of the queries solely by their *depth*.\n\n\n## Why?\n\nSuppose you have an `Album` type that has a list of `Song`s.\n\n```graphql\n{\n  album(id: 42) {\n    songs {\n      title\n      artists\n    }\n  }\n}\n```\n\nAnd perhaps you have a different entry point for a `Song` and the type allows you to go back up to the `Album`.\n\n```graphql\n{\n  song(id: 1337) {\n    title\n    album {\n      title\n    }\n  }\n}\n```\n\nThat opens your server to the possibility of a cyclical query!\n\n```graphql\nquery evil {\n  album(id: 42) {\n    songs {\n      album {\n        songs {\n          album {\n            songs {\n              album {\n                songs {\n                  album {\n                    songs {\n                      album {\n                        songs {\n                          album {\n                            # and so on...\n                          }\n                        }\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nHow would your server handle it if the query was 10,000 deep?\nThis may become a very expensive operation, at some point pinning a CPU on the server or perhaps the database.\nThis is a possible DOS vulnerability.\nWe want a way to validate the complexity of incoming queries.\n\nThis implementation lets you limit the **total depth** of each operation.\n\n## Quantifying Complexity\n\nDeciding exactly *when* a GraphQL query is \"too complex\" is a nuanced and subtle art.\nIt feels a bit like deciding how many grains of sand are needed to compose a \"pile of sand\".\nSome other libraries have the developer assign **costs** to parts of the schema, and adds the cumulative costs for each query.\n\n[graphql-validation-complexity](https://github.com/4Catalyzer/graphql-validation-complexity) does this based on the *types*,\nand [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity) does it based on each *field*.\n\nAdding up costs may work for some backends, but it does not always faithfully represent the complexity.\nBy adding the costs at each depth, it's as if the complexity is increasing lineraly with depth.\nSometimes the complexity actually increases **exponentially** with depth, for example if requesting a field means doing another SQL `JOIN`.\n\nThis library validates the total depth of the queries (and mutations).\n\n### Here's are some queries with a depth of 0\n\n```graphql\n# simplest possible query\nquery shallow1 {\n  thing1\n}\n\n# inline fragments don't actually increase the depth\nquery shallow2 {\n  thing1\n  ... on Query {\n    thing2\n  }\n}\n\n# neither do named fragments\nquery shallow3 {\n  ...queryFragment\n}\n\nfragment queryFragment on Query {\n  thing1\n}\n```\n\n### Deeper queries\n\n```graphql\n# depth = 1\nquery deep1_1 {\n  viewer {\n    name\n  }\n}\n\nquery deep1_2 {\n  viewer {\n    ... on User {\n      name\n    }\n  }\n}\n\n# depth = 2\nquery deep2 {\n  viewer {\n    albums {\n      title\n    }\n  }\n}\n\n# depth = 3\nquery deep3 {\n  viewer {\n    albums {\n      ...musicInfo\n      songs{\n        ...musicInfo\n      }\n    }\n  }\n}\n\nfragment musicInfo on Music {\n  id\n  title\n  artists\n}\n```\n\n## Usage\n\n```shell\n$ npm install graphql-depth-limit\n```\n\nIt works with [express-graphql](https://github.com/graphql/express-graphql) and [koa-graphql](https://github.com/chentsulin/koa-graphql).\nHere is an example with Express.\n\n```js\nimport depthLimit from 'graphql-depth-limit'\nimport express from 'express'\nimport graphqlHTTP from 'express-graphql'\nimport schema from './schema'\n\nconst app = express()\n\napp.use('/graphql', graphqlHTTP((req, res) => ({\n  schema,\n  validationRules: [ depthLimit(10) ]\n})))\n```\n\nThe first argument is the total depth limit. This will throw a validation error for queries (or mutations) with a depth of 11 or more.<br/>\nThe second argument is an options object, where you can do things like specify ignored fields. Introspection fields are ignored by default.<br/>\nThe third argument is a callback which receives an `Object` which is a map of the depths for each operation.<br/>\n\n```js\ndepthLimit(\n  10,\n  { ignore: [ /_trusted$/, 'idontcare' ] },\n  depths => console.log(depths)\n)\n```\n\nNow the evil query from before will tell the client this:\n\n```js\n{\n  \"errors\": [\n    {\n      \"message\": \"'evil' exceeds maximum operation depth of 10\",\n      \"locations\": [\n        {\n          \"line\": 13,\n          \"column\": 25\n        }\n      ]\n    }\n  ]\n}\n```\n\n## Future Work\n- [ ] Type-specific sub-depth limits, e.g. you can only descend 3 levels from an `Album` type, 5 levels from the `User` type, etc.\n- [ ] More customization options, like custom errors.\n\n## Documentation\n<a name=\"depthLimit\"></a>\n\n### depthLimit(maxDepth, [options], [callback]) ⇒ <code>function</code>\nCreates a validator for the GraphQL query depth\n\n**Kind**: global function  \n**Returns**: <code>function</code> - The validator function for GraphQL validation phase.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| maxDepth | <code>Number</code> | The maximum allowed depth for any operation in a GraphQL document. |\n| [options] | <code>Object</code> |  |\n| options.ignore | <code>String</code> \\| <code>RegExp</code> \\| <code>function</code> | Stops recursive depth checking based on a field name. Either a string or regexp to match the name, or a function that reaturns a boolean. |\n| [callback] | <code>function</code> | Called each time validation runs. Receives an Object which is a map of the depths for each operation. |\n\n","_attachments":{},"homepage":"https://github.com/stems/graphql-depth-limit#readme","bugs":{"url":"https://github.com/stems/graphql-depth-limit/issues"},"license":"MIT"}