{"componentChunkName":"component---src-templates-doc-tsx","path":"/learn/validation/","result":{"data":{"doc":{"frontmatter":{"title":"Validation","date":null,"permalink":"/learn/validation/","byline":null,"guestBio":null,"sublinks":null,"layout":"docs"},"id":"f69c6420-bf79-56a6-b7af-09fbe09f7565","rawMarkdownBody":"\nBy using the type system, it can be predetermined whether a GraphQL query\nis valid or not. This allows servers and clients to effectively inform\ndevelopers when an invalid query has been created, without having to rely\non runtime checks.\n\nFor our Star Wars example, the file\n[starWarsValidation-test.js](https://github.com/graphql/graphql-js/blob/master/src/__tests__/starWarsValidation-test.js)\ncontains a number of queries demonstrating various invalidities, and is a test\nfile that can be run to exercise the reference implementation's validator.\n\nTo start, let's take a complex valid query. This is a nested query, similar to\nan example from the previous section, but with the duplicated fields factored\nout into a fragment:\n\n```graphql\n# { \"graphiql\": true }\n{\n  hero {\n    ...NameAndAppearances\n    friends {\n      ...NameAndAppearances\n      friends {\n        ...NameAndAppearances\n      }\n    }\n  }\n}\n\nfragment NameAndAppearances on Character {\n  name\n  appearsIn\n}\n```\n\nAnd this query is valid. Let's take a look at some invalid queries...\n\nA fragment cannot refer to itself or create a cycle, as this could result in\nan unbounded result! Here's the same query above but without the explicit three\nlevels of nesting:\n\n```graphql\n# { \"graphiql\": true }\n{\n  hero {\n    ...NameAndAppearancesAndFriends\n  }\n}\n\nfragment NameAndAppearancesAndFriends on Character {\n  name\n  appearsIn\n  friends {\n    ...NameAndAppearancesAndFriends\n  }\n}\n```\n\nWhen we query for fields, we have to query for a field that exists on the\ngiven type. So as `hero` returns a `Character`, we have to query for a field\non `Character`. That type does not have a `favoriteSpaceship` field, so this\nquery is invalid:\n\n```graphql\n# { \"graphiql\": true }\n# INVALID: favoriteSpaceship does not exist on Character\n{\n  hero {\n    favoriteSpaceship\n  }\n}\n```\n\nWhenever we query for a field and it returns something other than a scalar\nor an enum, we need to specify what data we want to get back from the field.\nHero returns a `Character`, and we've been requesting fields like `name` and\n`appearsIn` on it; if we omit that, the query will not be valid:\n\n```graphql\n# { \"graphiql\": true }\n# INVALID: hero is not a scalar, so fields are needed\n{\n  hero\n}\n```\n\nSimilarly, if a field is a scalar, it doesn't make sense to query for\nadditional fields on it, and doing so will make the query invalid:\n\n```graphql\n# { \"graphiql\": true }\n# INVALID: name is a scalar, so fields are not permitted\n{\n  hero {\n    name {\n      firstCharacterOfName\n    }\n  }\n}\n```\n\nEarlier, it was noted that a query can only query for fields on the type\nin question; when we query for `hero` which returns a `Character`, we\ncan only query for fields that exist on `Character`. What happens if we\nwant to query for R2-D2s primary function, though?\n\n```graphql\n# { \"graphiql\": true }\n# INVALID: primaryFunction does not exist on Character\n{\n  hero {\n    name\n    primaryFunction\n  }\n}\n```\n\nThat query is invalid, because `primaryFunction` is not a field on `Character`.\nWe want some way of indicating that we wish to fetch `primaryFunction` if the\n`Character` is a `Droid`, and to ignore that field otherwise. We can use\nthe fragments we introduced earlier to do this. By setting up a fragment defined\non `Droid` and including it, we ensure that we only query for `primaryFunction`\nwhere it is defined.\n\n```graphql\n# { \"graphiql\": true }\n{\n  hero {\n    name\n    ...DroidFields\n  }\n}\n\nfragment DroidFields on Droid {\n  primaryFunction\n}\n```\n\nThis query is valid, but it's a bit verbose; named fragments were valuable\nabove when we used them multiple times, but we're only using this one once.\nInstead of using a named fragment, we can use an inline fragment; this\nstill allows us to indicate the type we are querying on, but without naming\na separate fragment:\n\n```graphql\n# { \"graphiql\": true }\n{\n  hero {\n    name\n    ... on Droid {\n      primaryFunction\n    }\n  }\n}\n```\n\nThis has just scratched the surface of the validation system; there\nare a number of validation rules in place to ensure that a GraphQL query\nis semantically meaningful. The specification goes into more detail about this\ntopic in the \"Validation\" section, and the\n[validation](https://github.com/graphql/graphql-js/blob/master/src/validation)\ndirectory in GraphQL.js contains code implementing a\nspecification-compliant GraphQL validator.\n"},"nextDoc":{"frontmatter":{"title":"Execution","permalink":"/learn/execution/"}}},"pageContext":{"permalink":"/learn/validation/","nextPermalink":"/learn/execution/","sideBarData":[{"name":"Learn","links":[{"fileAbsolutePath":"/opt/build/repo/src/content/learn/Introduction.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Introduction to GraphQL","permalink":"/learn/","next":"/learn/queries/","category":"Learn","sublinks":null,"sidebarTitle":"Introduction","date":null},"id":"7106674b-2f21-5d84-b8c3-c89c7e2b5561"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/Learn-Queries.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Queries and Mutations","permalink":"/learn/queries/","next":"/learn/schema/","category":"Learn","sublinks":"Fields,Arguments,Aliases,Fragments,Operation Name,Variables,Directives,Mutations,Inline Fragments","sidebarTitle":null,"date":null},"id":"d9731a25-3fbf-5586-ae79-95daca042058"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/Learn-Schema.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Schemas and Types","permalink":"/learn/schema/","next":"/learn/validation/","category":"Learn","sublinks":"Type System,Type Language,Object Types and Fields,Arguments,The Query and Mutation Types,Scalar Types,Enumeration Types,Lists and Non-Null,Interfaces,Union Types,Input Types","sidebarTitle":null,"date":null},"id":"6a9e1e57-c0ff-542e-a525-c28f658ad0a7"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/Learn-Validation.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Validation","permalink":"/learn/validation/","next":"/learn/execution/","category":"Learn","sublinks":null,"sidebarTitle":null,"date":null},"id":"f69c6420-bf79-56a6-b7af-09fbe09f7565"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/Learn-Execution.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Execution","permalink":"/learn/execution/","next":"/learn/introspection/","category":"Learn","sublinks":null,"sidebarTitle":null,"date":null},"id":"4d6ab3f1-c361-55eb-9800-797f90c3d8f6"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/Learn-Introspection.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Introspection","permalink":"/learn/introspection/","next":"/learn/best-practices/","category":"Learn","sublinks":null,"sidebarTitle":null,"date":null},"id":"2911ba27-f601-585a-a70f-3ad2cb78f9f3"}]},{"name":"Best Practices","links":[{"fileAbsolutePath":"/opt/build/repo/src/content/learn/BestPractice-Introduction.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"GraphQL Best Practices","permalink":"/learn/best-practices/","next":"/learn/thinking-in-graphs/","category":"Best Practices","sublinks":null,"sidebarTitle":"Introduction","date":null},"id":"2f5369f2-a0d4-5f71-972e-6569092db7a4"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/BestPractice-ThinkingInGraphs.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Thinking in Graphs","permalink":"/learn/thinking-in-graphs/","next":"/learn/serving-over-http/","category":"Best Practices","sublinks":null,"sidebarTitle":null,"date":null},"id":"692af90e-5600-50bd-bdd7-9048bc299512"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/BestPractice-ServingOverHTTP.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Serving over HTTP","permalink":"/learn/serving-over-http/","next":"/learn/authorization/","category":"Best Practices","sublinks":null,"sidebarTitle":null,"date":null},"id":"fbee8a12-2a83-51c2-b7f3-068438a89b9b"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/BestPractice-Authorization.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Authorization","permalink":"/learn/authorization/","next":"/learn/pagination/","category":"Best Practices","sublinks":null,"sidebarTitle":null,"date":null},"id":"2439b6ee-f2a2-5bbe-97d2-0f185a0b4aa8"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/BestPractice-Pagination.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Pagination","permalink":"/learn/pagination/","next":"/learn/global-object-identification/","category":"Best Practices","sublinks":null,"sidebarTitle":null,"date":null},"id":"5602cb49-7976-5673-8868-32155bd8b94e"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/BestPractice-NodeInterface.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Global Object Identification","permalink":"/learn/global-object-identification/","next":"/learn/caching/","category":"Best Practices","sublinks":null,"sidebarTitle":null,"date":null},"id":"62587b8a-8864-5487-b7db-8aacf4d0e464"},{"fileAbsolutePath":"/opt/build/repo/src/content/learn/BestPractice-Caching.md","parent":{"relativeDirectory":"learn","sourceInstanceName":"content"},"frontmatter":{"title":"Caching","permalink":"/learn/caching/","next":null,"category":"Best Practices","sublinks":null,"sidebarTitle":null,"date":null},"id":"64807002-e363-5637-aafc-4af37aa77f71"}]}],"sourcePath":"src/content/learn/Learn-Validation.md"}},"staticQueryHashes":["1581580458"]}