1"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([["17201"],{72571:function(e,n,s){s.r(n),s.d(n,{frontMatter:()=>t,toc:()=>d,default:()=>p,metadata:()=>i,assets:()=>l,contentTitle:()=>o});var i=JSON.parse('{"id":"modularization","title":"Modularization","description":"Ariadne allows you to spread your GraphQL API implementation over multiple files, with different strategies being available for schema and resolvers.","source":"@site/server_versioned_docs/version-0.9.0/modularization.md","sourceDirName":".","slug":"/modularization","permalink":"/server/0.9.0/modularization","draft":false,"unlisted":false,"tags":[],"version":"0.9.0","frontMatter":{"id":"modularization","title":"Modularization"},"sidebar":"tutorialSidebar","previous":{"title":"Documenting schema","permalink":"/server/0.9.0/documenting-schema"},"next":{"title":"Bindables","permalink":"/server/0.9.0/bindables"}}'),a=s(74848),r=s(84429);let t={id:"modularization",title:"Modularization"},o,l={},d=[{value:"Defining schema in <code>.graphql</code> files",id:"defining-schema-in-graphql-files",level:2},{value:"Defining schema in multiple modules",id:"defining-schema-in-multiple-modules",level:2},{value:"Defining types in multiple Python modules",id:"defining-types-in-multiple-python-modules",level:2}];function c(e){let n={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"Ariadne allows you to spread your GraphQL API implementation over multiple files, with different strategies being available for schema and resolvers."}),"\n",(0,a.jsxs)(n.h2,{id:"defining-schema-in-graphql-files",children:["Defining schema in ",(0,a.jsx)(n.code,{children:".graphql"})," files"]}),"\n",(0,a.jsxs)(n.p,{children:["The recommended way to define schema is by using ",(0,a.jsx)(n.code,{children:".graphql"})," files. This approach offers certain advantages:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["First class support from developer tools like ",(0,a.jsx)(n.a,{href:"https://marketplace.visualstudio.com/items?itemName=apollographql.vscode-apollo",children:"Apollo GraphQL plugin"})," for VS Code."]}),"\n",(0,a.jsx)(n.li,{children:"Easier cooperation and sharing of schema design between frontend and backend developers."}),"\n",(0,a.jsx)(n.li,{children:"Dropping whatever python boilerplate code was used for SDL strings."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["To load schema from a file or directory, you can use the ",(0,a.jsx)(n.code,{children:"load_schema_from_path"})," utility provided by the Ariadne:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:'from ariadne import load_schema_from_path\nfrom ariadne.asgi import GraphQL\n\n# Load schema from file...\ntype_defs = load_schema_from_path("/path/to/schema.graphql")\n\n# ...or construct schema from all *.graphql files in directory\ntype_defs = load_schema_from_path("/path/to/schema/")\n\n# Build an executable schema\nschema = make_executable_schema(type_defs)\n\n# Create an ASGI app for the schema\napp = GraphQL(schema)\n'})}),"\n",(0,a.jsx)(n.p,{children:"The above app won't be able to execute any queries but it will allow you to browse your schema."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"load_schema_from_path"})," validates syntax of every loaded file, and will raise an ",(0,a.jsx)(n.code,{children:"ariadne.exceptions.GraphQLFileSyntaxError"})," if file syntax is found to be invalid."]}),"\n",(0,a.jsx)(n.h2,{id:"defining-schema-in-multiple-modules",children:"Defining schema in multiple modules"}),"\n",(0,a.jsxs)(n.p,{children:["Because Ariadne expects ",(0,a.jsx)(n.code,{children:"type_defs"})," to be either a string or list of strings, it's easy to split types across many string variables in many modules:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:'query = """\n type Query {\n users: [User]!\n }\n"""\n\nuser = """\n type User {\n id: ID!\n username: String!\n joinedOn: Datetime!\n birthDay: Date!\n }\n"""\n\nscalars = """\n scalar Datetime\n scalar Date\n"""\n\nschema = make_executable_schema([query, user, scalars])\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The order in which types are defined or passed to ",(0,a.jsx)(n.code,{children:"type_defs"}
1)," doesn't matter, even if those types depend on each other."]}),"\n",(0,a.jsx)(n.h2,{id:"defining-types-in-multiple-python-modules",children:"Defining types in multiple Python modules"}),"\n",(0,a.jsxs)(n.p,{children:["GraphQL types definitions can be split across multiple modules or even packages, and combined using the ",(0,a.jsx)(n.code,{children:"make_executable_schema"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-console",children:"myapp/\n __init__.py\n ...\n graphql/\n types/\n __init__.py\n book.py\n query.py\n user.py\n __init__.py\n scalars.py\n schema.py\n"})}),"\n",(0,a.jsxs)(n.p,{children:["GraphQL types can be defined in dedicated modules under ",(0,a.jsx)(n.code,{children:"types"})," namespace and combined into a list in ",(0,a.jsx)(n.code,{children:"types/__init__.py"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:"from .book import book\nfrom .query import query\nfrom .user import user\n\ntypes = [query, book, user]\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Because API defines only single custom scalar, using single ",(0,a.jsx)(n.code,{children:"scalars.py"})," module can be enough:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:'from ariadne import ScalarType\n\n\nisbn = ScalarType("ISBN")\n\n... # other code for isbn scalar\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"schema.py"})," imports ",(0,a.jsx)(n.code,{children:"types"})," list and single custom scalar, then passes those as ",(0,a.jsx)(n.code,{children:"*args"})," to ",(0,a.jsx)(n.code,{children:"make_executable_schema"})," to combine them into single schema:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:"from .types import types\nfrom .scalars import isbn\n\ntype_defs = ... # valid type definitions\n\nschema = make_executable_schema(type_defs, *types, isbn)\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The order in which objects are passed to the ",(0,a.jsx)(n.code,{children:"bindables"})," argument matters. Most bindables replace previously set resolvers with new ones, when more than one is defined for the same GraphQL type, with ",(0,a.jsx)(n.code,{children:"InterfaceType"})," and fallback resolvers being exceptions to this rule."]})]})}function p(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},84429:function(e,n,s){s.d(n,{R:()=>t,x:()=>o});var i=s(96540);let a={},r=i.createContext(a);function t(e){let n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.