{"componentChunkName":"component---src-templates-doc-tsx","path":"/learn/thinking-in-graphs/","result":{"data":{"doc":{"frontmatter":{"title":"Thinking in Graphs","date":null,"permalink":"/learn/thinking-in-graphs/","byline":null,"guestBio":null,"sublinks":null,"layout":"docs"},"id":"692af90e-5600-50bd-bdd7-9048bc299512","rawMarkdownBody":"\n## It's Graphs All the Way Down [\\*](https://en.wikipedia.org/wiki/Turtles_all_the_way_down)\n> With GraphQL, you model your business domain as a graph\n\nGraphs are powerful tools for modeling many real-world phenomena because they resemble our natural mental models and verbal descriptions of the underlying process. With GraphQL, you model your business domain as a graph by defining a schema; within your schema, you define different types of nodes and how they connect/relate to one another. On the client, this creates a pattern similar to Object-Oriented Programming: types that reference other types. On the server, since GraphQL only defines the interface, you have the freedom to use it with any backend (new or legacy!).\n\n## Shared Language\n> Naming things is a hard but important part of building intuitive APIs\n\nThink of your GraphQL schema as an expressive shared language for your team and your users. To build a good schema, examine the everyday language you use to describe your business. For example, let's try to describe an email app in plain English:\n\n* A user can have multiple email accounts\n* Each email account has an address, inbox, drafts, deleted items, and sent items\n* Each email has a sender, receive date, subject, and body\n* Users cannot send an email without a recipient address\n\nNaming things is a hard but important part of building intuitive APIs, so take time to carefully think about what makes sense for your problem domain and users. Your team should develop a shared understanding and consensus of these business domain rules because you will need to choose intuitive, durable names for nodes and relationships in the GraphQL schema. Try to imagine some of the queries you will want to execute:\n\nFetch the number of unread emails in my inbox for all my accounts\n```graphql\n{\n  accounts {\n    inbox {\n      unreadEmailCount\n    }\n  }\n}\n```\n\nFetch the \"preview info\" for the first 20 drafts in the main account\n```graphql\n{\n  mainAccount {\n    drafts(first: 20) {\n      ...previewInfo\n    }\n  }\n}\n\nfragment previewInfo on Email {\n  subject\n  bodyPreviewSentence\n}\n```\n\n## Business Logic Layer\n> Your business logic layer should act as the single source of truth for enforcing business domain rules\n\nWhere should you define the actual business logic? Where should you perform validation and authorization checks? The answer: inside a dedicated business logic layer. Your business logic layer should act as the single source of truth for enforcing business domain rules.\n\n![Business Logic Layer Diagram](/img/diagrams/business_layer.png)\n\nIn the diagram above, all entry points (REST, GraphQL, and RPC) into the system will be processed with the same validation, authorization, and error handling rules.\n\n### Working with Legacy Data\n> Prefer building a GraphQL schema that describes how clients use the data, rather than mirroring the legacy database schema.\n\nSometimes, you will find yourself working with legacy data sources that do not perfectly reflect how clients consume the data. In these cases, prefer building a GraphQL schema that describes how clients use the data, rather than mirroring the legacy database schema.\n\nBuild your GraphQL schema to express \"what\" rather than \"how\". Then you can improve your implementation details without breaking the interface with older clients.\n\n## One Step at a time\n> Get validation and feedback more frequently\n\nDon't try to model your entire business domain in one sitting. Rather, build only the part of the schema that you need for one scenario at a time. By gradually expanding the schema, you will get validation and feedback more frequently to steer you toward building the right solution.\n"},"nextDoc":{"frontmatter":{"title":"Serving over HTTP","permalink":"/learn/serving-over-http/"}}},"pageContext":{"permalink":"/learn/thinking-in-graphs/","nextPermalink":"/learn/serving-over-http/","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/BestPractice-ThinkingInGraphs.md"}},"staticQueryHashes":["1581580458"]}