From 292b7e035b44fc9cdb6747788d854dc8d6c2f7ab Mon Sep 17 00:00:00 2001 From: vladar Date: Fri, 25 Nov 2016 18:10:10 +0700 Subject: [PATCH] Deployed 961e44c with MkDocs version: 0.15.3 --- complementary-tools/index.html | 37 +++++----- error-handling/index.html | 29 +++----- executing-queries/index.html | 16 +---- getting-started/index.html | 29 +++----- index.html | 32 ++++----- mkdocs/search_index.json | 88 ++++++++++------------- search.html | 14 ---- sitemap.xml | 46 ++++-------- type-system/directives/index.html | 14 ---- type-system/enum-types/index.html | 18 +---- type-system/index.html | 42 +---------- type-system/input-types/index.html | 14 ---- type-system/interfaces/index.html | 18 +---- type-system/lists-and-nonnulls/index.html | 14 ---- type-system/object-types/index.html | 18 +---- type-system/scalar-types/index.html | 57 +++------------ type-system/schema/index.html | 14 ---- type-system/unions/index.html | 18 +---- 18 files changed, 125 insertions(+), 393 deletions(-) diff --git a/complementary-tools/index.html b/complementary-tools/index.html index d5dcdf0..4605164 100755 --- a/complementary-tools/index.html +++ b/complementary-tools/index.html @@ -157,20 +157,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -180,10 +166,10 @@ @@ -223,8 +209,19 @@
    -

    Relay

    -

    GraphiQL

    +

    Integrations

    + +

    Tools

    +
    @@ -233,7 +230,7 @@ @@ -259,7 +256,7 @@ - « Previous + « Previous diff --git a/error-handling/index.html b/error-handling/index.html index b98eb72..07627e4 100755 --- a/error-handling/index.html +++ b/error-handling/index.html @@ -173,20 +173,6 @@ -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -334,14 +320,17 @@ when it makes sense to return 500 error code for GraphQL endpoint:< // ... ]); - $result = GraphQL::execute($schema, $query); + $body = GraphQL::execute($schema, $query); + $status = 200; } catch(\Exception $e) { - header('Content-Type: application/json', true, 500); - echo json_encode([ + $body = json_encode([ 'message' => 'Unexpected error' ]); - exit; + $status = 500; } + +header('Content-Type: application/json', true, $status); +echo json_encode($body); @@ -350,7 +339,7 @@ when it makes sense to return 500 error code for GraphQL endpoint:< diff --git a/executing-queries/index.html b/executing-queries/index.html index c9b4519..b78f1c2 100755 --- a/executing-queries/index.html +++ b/executing-queries/index.html @@ -173,20 +173,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -266,7 +252,7 @@ See also section on error handling.

    queryString -string or GraphQL\Language\AST\Document +string or GraphQL\Language\AST\DocumentNode Required. Actual GraphQL query string to be parsed, validated and executed. If you parse query elsewhere before executing - pass corresponding ast document here to avoid new parsing. diff --git a/getting-started/index.html b/getting-started/index.html index e4e3273..4cf674a 100755 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -73,6 +73,9 @@
  • Installation
  • +
  • Upgrading
  • + +
  • Install Tools (optional)
  • @@ -176,20 +179,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -240,14 +229,16 @@ first learn about GraphQL on official websi add composer.json file to your project root folder with following contents:

    {
         "require": {
    -        "webonyx/graphql-php": "^0.7"
    +        "webonyx/graphql-php": "^0.8"
         }
     }
     

    and run composer install.

    -

    If you already have composer.json file - simply run: composer require webonyx/graphql-php

    -

    If you are upgrading, see upgrade instructions

    +

    If you already have composer.json file - simply run: composer require webonyx/graphql-php="^0.8"

    +

    Upgrading

    +

    We try to keep library releases backwards compatible. But when breaking changes are inevitable +they are explained in upgrade instructions.

    Install Tools (optional)

    While it is possible to communicate with GraphQL API using regular HTTP tools it is way more convenient for humans to use GraphiQL - an in-browser @@ -263,7 +254,7 @@ GraphQL API.

    page and install it locally.

    Hello World

    Let's create type system that will be capable to process following simple query:

    -
    query { 
    +
    query {
       echo(message: "Hello World")
     }
     
    @@ -290,7 +281,7 @@ $queryType = new ObjectType([

    (Note: type definition can be expressed in different styles, -including inheritance, composition and inline. This example uses inline style for simplicity)

    +but this example uses inline style for simplicity)

    The interesting piece here is resolve option of field definition. It is responsible for retuning value of our field. Values of scalar fields will be directly included in response while values of complex fields (objects, interfaces, unions) will be passed down to nested field resolvers diff --git a/index.html b/index.html index 814f071..bd88f2d 100755 --- a/index.html +++ b/index.html @@ -67,6 +67,8 @@

  • Current Status
  • +
  • Github
  • + @@ -169,20 +171,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -225,7 +213,12 @@
    -

    About GraphQL

    +

    GitHub stars +Build Status +Coverage Status +Latest Stable Version +License

    +

    About GraphQL

    GraphQL is a modern way to build HTTP APIs consumed by web and mobile clients. It is intended to be a replacement for REST and SOAP APIs (even for existing applications).

    GraphQL itself is a specification designed by Facebook @@ -243,7 +236,7 @@ are used. Instead it provides tools for creating rich API for your existing app.

    These tools include:

    • Primitives to express your app as a Type System
    • -
    • Tools for validation and introspection of this Type System (for compatibility with tools like GraphiQL)
    • +
    • Tools for validation and introspection of this Type System (for compatibility with tools like GraphiQL)
    • Tools for parsing, validating and executing GraphQL queries against this Type System
    • Rich error reporting, including query validation and execution errors
    • Optional tools for parsing GraphQL Schema Definition language
    • @@ -251,10 +244,13 @@ are used. Instead it provides tools for creating rich API for your existing app.

      Also several complementary tools are available which provide integrations with existing PHP frameworks, add support for Relay, etc.

      Current Status

      -

      Current version supports all features described by GraphQL specification +

      First version of this library (v0.1) was released on August 10th 2015.

      +

      Current version (v0.7) supports all features described by GraphQL specification (including April 2016 add-ons) as well as some experimental features like Schema Language parser.

      Ready for real-world usage.

      +

      Github

      +

      Project source code is hosted on GitHub.

    @@ -300,5 +296,5 @@ Schema Language parser.

    diff --git a/mkdocs/search_index.json b/mkdocs/search_index.json index 8033b1c..0b5d0c1 100755 --- a/mkdocs/search_index.json +++ b/mkdocs/search_index.json @@ -2,7 +2,7 @@ "docs": [ { "location": "/", - "text": "About GraphQL\n\n\nGraphQL is a modern way to build HTTP APIs consumed by web and mobile clients.\nIt is intended to be a replacement for REST and SOAP APIs (even for \nexisting applications\n).\n\n\nGraphQL itself is a \nspecification\n designed by Facebook\nengineers. Various implementations of this specification were written \n\nfor different languages and environments\n.\n\n\nGreat overview of GraphQL features and benefits is presented on \nofficial website\n. \nAll of them equally apply to this PHP implementation. \n\n\nAbout graphql-php\n\n\ngraphql-php\n is a feature-complete implementation of GraphQL specification in PHP (5.4+, 7.0+). \nIt was originally inspired by \nreference JavaScript implementation\n \npublished by Facebook.\n\n\nThis library is a thin wrapper around your existing data layer and business logic. \nIt doesn't dictate how these layers are implemented or which storage engines \nare used. Instead it provides tools for creating rich API for your existing app. \n\n\nThese tools include:\n\n\n\n\nPrimitives to express your app as a Type System\n\n\nTools for validation and introspection of this Type System (for compatibility with tools like \nGraphiQL\n)\n\n\nTools for parsing, validating and executing GraphQL queries against this Type System\n\n\nRich error reporting, including query validation and execution errors\n\n\nOptional tools for parsing GraphQL Schema Definition language\n\n\n\n\nAlso several \ncomplementary tools\n are available which provide integrations with \nexisting PHP frameworks, add support for Relay, etc.\n\n\nCurrent Status\n\n\nCurrent version supports all features described by GraphQL specification \n(including April 2016 add-ons) as well as some experimental features like \nSchema Language parser.\n\n\nReady for real-world usage.", + "text": "About GraphQL\n\n\nGraphQL is a modern way to build HTTP APIs consumed by web and mobile clients.\nIt is intended to be a replacement for REST and SOAP APIs (even for \nexisting applications\n).\n\n\nGraphQL itself is a \nspecification\n designed by Facebook\nengineers. Various implementations of this specification were written \n\nfor different languages and environments\n.\n\n\nGreat overview of GraphQL features and benefits is presented on \nofficial website\n. \nAll of them equally apply to this PHP implementation. \n\n\nAbout graphql-php\n\n\ngraphql-php\n is a feature-complete implementation of GraphQL specification in PHP (5.4+, 7.0+). \nIt was originally inspired by \nreference JavaScript implementation\n \npublished by Facebook.\n\n\nThis library is a thin wrapper around your existing data layer and business logic. \nIt doesn't dictate how these layers are implemented or which storage engines \nare used. Instead it provides tools for creating rich API for your existing app. \n\n\nThese tools include:\n\n\n\n\nPrimitives to express your app as a Type System\n\n\nTools for validation and introspection of this Type System (for compatibility with tools like \nGraphiQL\n)\n\n\nTools for parsing, validating and executing GraphQL queries against this Type System\n\n\nRich error reporting, including query validation and execution errors\n\n\nOptional tools for parsing GraphQL Schema Definition language\n\n\n\n\nAlso several \ncomplementary tools\n are available which provide integrations with \nexisting PHP frameworks, add support for Relay, etc.\n\n\nCurrent Status\n\n\nFirst version of this library (v0.1) was released on August 10th 2015.\n\n\nCurrent version (v0.7) supports all features described by GraphQL specification \n(including April 2016 add-ons) as well as some experimental features like \nSchema Language parser.\n\n\nReady for real-world usage.\n\n\nGithub\n\n\nProject source code is \nhosted on GitHub\n.", "title": "About" }, { @@ -17,12 +17,17 @@ }, { "location": "/#current-status", - "text": "Current version supports all features described by GraphQL specification \n(including April 2016 add-ons) as well as some experimental features like \nSchema Language parser. Ready for real-world usage.", + "text": "First version of this library (v0.1) was released on August 10th 2015. Current version (v0.7) supports all features described by GraphQL specification \n(including April 2016 add-ons) as well as some experimental features like \nSchema Language parser. Ready for real-world usage.", "title": "Current Status" }, + { + "location": "/#github", + "text": "Project source code is hosted on GitHub .", + "title": "Github" + }, { "location": "/getting-started/", - "text": "Prerequisites\n\n\nThis documentation assumes your familiarity with GraphQL concepts. If it is not the case - \nfirst learn about GraphQL on \nofficial website\n.\n\n\nInstallation\n\n\nUsing \ncomposer\n:\nadd \ncomposer.json\n file to your project root folder with following contents:\n\n\n{\n \nrequire\n: {\n \nwebonyx/graphql-php\n: \n^0.7\n\n }\n}\n\n\n\n\nand run \ncomposer install\n. \n\n\nIf you already have composer.json file - simply run: \ncomposer require webonyx/graphql-php\n\n\nIf you are upgrading, see \nupgrade instructions\n\n\nInstall Tools (optional)\n\n\nWhile it is possible to communicate with GraphQL API using regular HTTP tools it is way \nmore convenient for humans to use \nGraphiQL\n - an in-browser \nide for exploring GraphQL APIs.\n\n\nIt provides syntax-highlighting, auto-completion and auto-generated documentation for \nGraphQL API.\n\n\nThe easiest way to use it is to install one of the existing Google Chrome extensions:\n\n\n\n\nChromeiQL\n\n\nGraphiQL Feen\n\n\n\n\nAlternatively you can follow instructions on \nGraphiQL\n\npage and install it locally.\n\n\nHello World\n\n\nLet's create type system that will be capable to process following simple query:\n\n\nquery { \n echo(message: \nHello World\n)\n}\n\n\n\n\nTo do so we need an object type with field \necho\n:\n\n\n?php\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$queryType = new ObjectType([\n 'name' =\n 'Query',\n 'fields' =\n [\n 'echo' =\n [\n 'type' =\n Type::string(),\n 'args' =\n [\n 'message' =\n Type::nonNull(Type::string()),\n ],\n 'resolve' =\n function ($root, $args) {\n return $root['prefix'] . $args['message'];\n }\n ],\n ],\n]);\n\n\n\n\n(Note: type definition can be expressed in \ndifferent styles\n, \nincluding \ninheritance\n, \ncomposition\n and \ninline\n. This example uses \ninline\n style for simplicity)\n\n\nThe interesting piece here is \nresolve\n option of field definition. It is responsible for retuning \nvalue of our field. Values of \nscalar\n fields will be directly included in response while values of \n\ncomplex\n fields (objects, interfaces, unions) will be passed down to nested field resolvers \n(not in this example though).\n\n\nNow when our type is ready, let's create GraphQL endpoint for it \ngraphql.php\n:\n\n\n?php\nuse GraphQL\\GraphQL;\nuse GraphQL\\Schema;\n\n$schema = new Schema([\n 'query' =\n $queryType\n]);\n\n$rawInput = file_get_contents('php://input');\n\ntry {\n $rootValue = ['prefix' =\n 'You said: '];\n $result = GraphQL::execute($schema, $rawInput, $rootValue);\n} catch (\\Exception $e) {\n $result = [\n 'error' =\n [\n 'message' =\n $e-\ngetMessage()\n ]\n ];\n}\nheader('Content-Type: application/json; charset=UTF-8');\necho json_encode($result);\n\n\n\n\nOur example is ready. Try it by running:\n\n\nphp -S localhost:8000 graphql.php\ncurl http://localhost:8000 -d \nquery { echo(message: \\\nHello World\\\n) }\n\n\n\n\n\nCheck out the full \nsource code\n of this example.\n\n\nObviously hello world only scratches the surface of what is possible. \nSo check out next example, which is closer to real-world apps.\nOr keep reading about \nschema definition\n.\n\n\nBlog example\n\n\nIt is often easier to start with full-featured example and then get back to documentation\nfor your own work. \n\n\nCheck out \nBlog example of GraphQL API\n.\nIt is quite close to real-world GraphQL hierarchies. Follow instructions and try it yourself in ~10 minutes.", + "text": "Prerequisites\n\n\nThis documentation assumes your familiarity with GraphQL concepts. If it is not the case - \nfirst learn about GraphQL on \nofficial website\n.\n\n\nInstallation\n\n\nUsing \ncomposer\n:\nadd \ncomposer.json\n file to your project root folder with following contents:\n\n\n{\n \nrequire\n: {\n \nwebonyx/graphql-php\n: \n^0.8\n\n }\n}\n\n\n\n\nand run \ncomposer install\n. \n\n\nIf you already have composer.json file - simply run: \ncomposer require webonyx/graphql-php=\"^0.8\"\n\n\nUpgrading\n\n\nWe try to keep library releases backwards compatible. But when breaking changes are inevitable \nthey are explained in \nupgrade instructions\n.\n\n\nInstall Tools (optional)\n\n\nWhile it is possible to communicate with GraphQL API using regular HTTP tools it is way \nmore convenient for humans to use \nGraphiQL\n - an in-browser \nide for exploring GraphQL APIs.\n\n\nIt provides syntax-highlighting, auto-completion and auto-generated documentation for \nGraphQL API.\n\n\nThe easiest way to use it is to install one of the existing Google Chrome extensions:\n\n\n\n\nChromeiQL\n\n\nGraphiQL Feen\n\n\n\n\nAlternatively you can follow instructions on \nGraphiQL\n\npage and install it locally.\n\n\nHello World\n\n\nLet's create type system that will be capable to process following simple query:\n\n\nquery {\n echo(message: \nHello World\n)\n}\n\n\n\n\nTo do so we need an object type with field \necho\n:\n\n\n?php\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$queryType = new ObjectType([\n 'name' =\n 'Query',\n 'fields' =\n [\n 'echo' =\n [\n 'type' =\n Type::string(),\n 'args' =\n [\n 'message' =\n Type::nonNull(Type::string()),\n ],\n 'resolve' =\n function ($root, $args) {\n return $root['prefix'] . $args['message'];\n }\n ],\n ],\n]);\n\n\n\n\n(Note: type definition can be expressed in \ndifferent styles\n, \nbut this example uses \ninline\n style for simplicity)\n\n\nThe interesting piece here is \nresolve\n option of field definition. It is responsible for retuning \nvalue of our field. Values of \nscalar\n fields will be directly included in response while values of \n\ncomplex\n fields (objects, interfaces, unions) will be passed down to nested field resolvers \n(not in this example though).\n\n\nNow when our type is ready, let's create GraphQL endpoint for it \ngraphql.php\n:\n\n\n?php\nuse GraphQL\\GraphQL;\nuse GraphQL\\Schema;\n\n$schema = new Schema([\n 'query' =\n $queryType\n]);\n\n$rawInput = file_get_contents('php://input');\n\ntry {\n $rootValue = ['prefix' =\n 'You said: '];\n $result = GraphQL::execute($schema, $rawInput, $rootValue);\n} catch (\\Exception $e) {\n $result = [\n 'error' =\n [\n 'message' =\n $e-\ngetMessage()\n ]\n ];\n}\nheader('Content-Type: application/json; charset=UTF-8');\necho json_encode($result);\n\n\n\n\nOur example is ready. Try it by running:\n\n\nphp -S localhost:8000 graphql.php\ncurl http://localhost:8000 -d \nquery { echo(message: \\\nHello World\\\n) }\n\n\n\n\n\nCheck out the full \nsource code\n of this example.\n\n\nObviously hello world only scratches the surface of what is possible. \nSo check out next example, which is closer to real-world apps.\nOr keep reading about \nschema definition\n.\n\n\nBlog example\n\n\nIt is often easier to start with full-featured example and then get back to documentation\nfor your own work. \n\n\nCheck out \nBlog example of GraphQL API\n.\nIt is quite close to real-world GraphQL hierarchies. Follow instructions and try it yourself in ~10 minutes.", "title": "Getting Started" }, { @@ -32,9 +37,14 @@ }, { "location": "/getting-started/#installation", - "text": "Using composer :\nadd composer.json file to your project root folder with following contents: {\n require : {\n webonyx/graphql-php : ^0.7 \n }\n} and run composer install . If you already have composer.json file - simply run: composer require webonyx/graphql-php If you are upgrading, see upgrade instructions", + "text": "Using composer :\nadd composer.json file to your project root folder with following contents: {\n require : {\n webonyx/graphql-php : ^0.8 \n }\n} and run composer install . If you already have composer.json file - simply run: composer require webonyx/graphql-php=\"^0.8\"", "title": "Installation" }, + { + "location": "/getting-started/#upgrading", + "text": "We try to keep library releases backwards compatible. But when breaking changes are inevitable \nthey are explained in upgrade instructions .", + "title": "Upgrading" + }, { "location": "/getting-started/#install-tools-optional", "text": "While it is possible to communicate with GraphQL API using regular HTTP tools it is way \nmore convenient for humans to use GraphiQL - an in-browser \nide for exploring GraphQL APIs. It provides syntax-highlighting, auto-completion and auto-generated documentation for \nGraphQL API. The easiest way to use it is to install one of the existing Google Chrome extensions: ChromeiQL GraphiQL Feen Alternatively you can follow instructions on GraphiQL \npage and install it locally.", @@ -42,7 +52,7 @@ }, { "location": "/getting-started/#hello-world", - "text": "Let's create type system that will be capable to process following simple query: query { \n echo(message: Hello World )\n} To do so we need an object type with field echo : ?php\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$queryType = new ObjectType([\n 'name' = 'Query',\n 'fields' = [\n 'echo' = [\n 'type' = Type::string(),\n 'args' = [\n 'message' = Type::nonNull(Type::string()),\n ],\n 'resolve' = function ($root, $args) {\n return $root['prefix'] . $args['message'];\n }\n ],\n ],\n]); (Note: type definition can be expressed in different styles , \nincluding inheritance , composition and inline . This example uses inline style for simplicity) The interesting piece here is resolve option of field definition. It is responsible for retuning \nvalue of our field. Values of scalar fields will be directly included in response while values of complex fields (objects, interfaces, unions) will be passed down to nested field resolvers \n(not in this example though). Now when our type is ready, let's create GraphQL endpoint for it graphql.php : ?php\nuse GraphQL\\GraphQL;\nuse GraphQL\\Schema;\n\n$schema = new Schema([\n 'query' = $queryType\n]);\n\n$rawInput = file_get_contents('php://input');\n\ntry {\n $rootValue = ['prefix' = 'You said: '];\n $result = GraphQL::execute($schema, $rawInput, $rootValue);\n} catch (\\Exception $e) {\n $result = [\n 'error' = [\n 'message' = $e- getMessage()\n ]\n ];\n}\nheader('Content-Type: application/json; charset=UTF-8');\necho json_encode($result); Our example is ready. Try it by running: php -S localhost:8000 graphql.php\ncurl http://localhost:8000 -d query { echo(message: \\ Hello World\\ ) } Check out the full source code of this example. Obviously hello world only scratches the surface of what is possible. \nSo check out next example, which is closer to real-world apps.\nOr keep reading about schema definition .", + "text": "Let's create type system that will be capable to process following simple query: query {\n echo(message: Hello World )\n} To do so we need an object type with field echo : ?php\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$queryType = new ObjectType([\n 'name' = 'Query',\n 'fields' = [\n 'echo' = [\n 'type' = Type::string(),\n 'args' = [\n 'message' = Type::nonNull(Type::string()),\n ],\n 'resolve' = function ($root, $args) {\n return $root['prefix'] . $args['message'];\n }\n ],\n ],\n]); (Note: type definition can be expressed in different styles , \nbut this example uses inline style for simplicity) The interesting piece here is resolve option of field definition. It is responsible for retuning \nvalue of our field. Values of scalar fields will be directly included in response while values of complex fields (objects, interfaces, unions) will be passed down to nested field resolvers \n(not in this example though). Now when our type is ready, let's create GraphQL endpoint for it graphql.php : ?php\nuse GraphQL\\GraphQL;\nuse GraphQL\\Schema;\n\n$schema = new Schema([\n 'query' = $queryType\n]);\n\n$rawInput = file_get_contents('php://input');\n\ntry {\n $rootValue = ['prefix' = 'You said: '];\n $result = GraphQL::execute($schema, $rawInput, $rootValue);\n} catch (\\Exception $e) {\n $result = [\n 'error' = [\n 'message' = $e- getMessage()\n ]\n ];\n}\nheader('Content-Type: application/json; charset=UTF-8');\necho json_encode($result); Our example is ready. Try it by running: php -S localhost:8000 graphql.php\ncurl http://localhost:8000 -d query { echo(message: \\ Hello World\\ ) } Check out the full source code of this example. Obviously hello world only scratches the surface of what is possible. \nSo check out next example, which is closer to real-world apps.\nOr keep reading about schema definition .", "title": "Hello World" }, { @@ -52,7 +62,7 @@ }, { "location": "/type-system/", - "text": "Type System\n\n\nTo start using GraphQL you are expected to implement a type hierarchy and expose it as \nSchema\n. \n\n\nIn \ngraphql-php\n \ntype\n is an instance of internal class from \n\nGraphQL\\Type\\Definition\n namespace: \nScalarType\n, \nObjectType\n, \nInterfaceType\n, \n\nUnionType\n, \nInputObjectType\n (or one of it's subclasses).\n\n\nBut most of the types in your schema will be \nobject types\n.\n\n\nType Definition Styles\n\n\nSeveral styles of type definitions are supported depending on your preferences.\n\n\nInline definitions:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$myType = new ObjectType([\n 'name' =\n 'MyType',\n 'fields' =\n [\n 'id' =\n Type::id()\n ]\n]);\n\n\n\n\nClass per type, using inheritance:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass MyType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n // Note: 'name' is not needed in this form:\n // it will be inferred from class name by omitting namespace and dropping \nType\n suffix\n 'fields' =\n [\n 'id' =\n Type::id()\n ]\n ];\n parent::__construct($config);\n }\n}\n\n\n\n\nClass per type, using composition:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\DefinitionContainer;\n\nclass MyType implements DefinitionContainer\n{\n private $definition;\n\n public function getDefinition()\n {\n return $this-\ndefinition ?: ($this-\ndefinition = new ObjectType([\n 'name' =\n 'MyType',\n 'fields' =\n [\n 'id' =\n Type::id()\n ]\n ]));\n }\n}\n\n\n\n\nYou can also mix-and-match styles for convenience. For example:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass BlogPostType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n 'fields' =\n [\n 'body' =\n new ObjectType([\n 'name' =\n 'BlogPostBody',\n 'fields' =\n [\n 'html' =\n Type::string(),\n 'text' =\n Type::string(),\n ]\n ])\n ]\n ];\n parent::__construct($config);\n }\n}\n\n\n\n\nType Registry\n\n\nEvery type must be presented in Schema with single instance (\ngraphql-php\n \nthrows when it discovers several instances with the same \nname\n in schema).\n\n\nTherefore if you define your type as separate PHP class you must ensure that only one \ninstance of that class is added to schema.\n\n\nTypical way to do this is to create registry of your types:\n\n\n?php\nnamespace MyApp;\n\nclass TypeRegistry\n{\n private $myAType;\n private $myBType;\n\n public function myAType()\n {\n return $this-\nmyAType ?: ($this-\nmyAType = new MyAType($this));\n }\n\n public function myBType()\n {\n return $this-\nmyBType ?: ($this-\nmyBType = new MyBType($this));\n }\n}\n\n\n\n\nAnd use this registry in type definition:\n\n\n?php\nnamespace MyApp;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\nclass MyAType extends ObjectType\n{\n public function __construct(TypeRegistry $types) \n {\n parent::__construct([\n 'fields' =\n [\n 'b' =\n $types-\nmyBType() \n ]\n ]);\n }\n}\n\n\n\n\nObviously you can automate this registry as you wish to reduce boilerplate or even \nintroduce Dependency Injection Container if your types have other dependencies.\n\n\nAlternatively all methods of registry could be static if you prefer - then there is no need\nto pass it in constructor - instead just use use \nTypeRegistry::myAType()\n in your type definitions.", + "text": "Type System\n\n\nTo start using GraphQL you are expected to implement a type hierarchy and expose it as \nSchema\n. \n\n\nIn \ngraphql-php\n \ntype\n is an instance of internal class from \n\nGraphQL\\Type\\Definition\n namespace: \nScalarType\n, \nObjectType\n, \nInterfaceType\n, \n\nUnionType\n, \nInputObjectType\n (or one of it's subclasses).\n\n\nBut most of the types in your schema will be \nobject types\n.\n\n\nType Definition Styles\n\n\nSeveral styles of type definitions are supported depending on your preferences.\n\n\nInline definitions:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$myType = new ObjectType([\n 'name' =\n 'MyType',\n 'fields' =\n [\n 'id' =\n Type::id()\n ]\n]);\n\n\n\n\nClass per type:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass MyType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n // Note: 'name' is not needed in this form:\n // it will be inferred from class name by omitting namespace and dropping \nType\n suffix\n 'fields' =\n [\n 'id' =\n Type::id()\n ]\n ];\n parent::__construct($config);\n }\n}\n\n\n\n\nYou can also mix-and-match styles for convenience. For example:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass BlogPostType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n 'fields' =\n [\n 'body' =\n new ObjectType([\n 'name' =\n 'BlogPostBody',\n 'fields' =\n [\n 'html' =\n Type::string(),\n 'text' =\n Type::string(),\n ]\n ])\n ]\n ];\n parent::__construct($config);\n }\n}\n\n\n\n\nType Registry\n\n\nEvery type must be presented in Schema by single instance (\ngraphql-php\n \nthrows when it discovers several instances with the same \nname\n in schema).\n\n\nTherefore if you define your type as separate PHP class you must ensure that only one \ninstance of that class is added to schema.\n\n\nTypical way to do this is to create registry of your types:\n\n\n?php\nnamespace MyApp;\n\nclass TypeRegistry\n{\n private $myAType;\n private $myBType;\n\n public function myAType()\n {\n return $this-\nmyAType ?: ($this-\nmyAType = new MyAType($this));\n }\n\n public function myBType()\n {\n return $this-\nmyBType ?: ($this-\nmyBType = new MyBType($this));\n }\n}\n\n\n\n\nAnd use this registry in type definition:\n\n\n?php\nnamespace MyApp;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\nclass MyAType extends ObjectType\n{\n public function __construct(TypeRegistry $types) \n {\n parent::__construct([\n 'fields' =\n [\n 'b' =\n $types-\nmyBType() \n ]\n ]);\n }\n}\n\n\n\n\nObviously you can automate this registry as you wish to reduce boilerplate or even \nintroduce Dependency Injection Container if your types have other dependencies.\n\n\nAlternatively all methods of registry could be static if you prefer - then there is no need\nto pass it in constructor - instead just use use \nTypeRegistry::myAType()\n in your type definitions.", "title": "Introduction" }, { @@ -62,22 +72,22 @@ }, { "location": "/type-system/#type-definition-styles", - "text": "Several styles of type definitions are supported depending on your preferences. Inline definitions: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$myType = new ObjectType([\n 'name' = 'MyType',\n 'fields' = [\n 'id' = Type::id()\n ]\n]); Class per type, using inheritance: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass MyType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n // Note: 'name' is not needed in this form:\n // it will be inferred from class name by omitting namespace and dropping Type suffix\n 'fields' = [\n 'id' = Type::id()\n ]\n ];\n parent::__construct($config);\n }\n} Class per type, using composition: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\DefinitionContainer;\n\nclass MyType implements DefinitionContainer\n{\n private $definition;\n\n public function getDefinition()\n {\n return $this- definition ?: ($this- definition = new ObjectType([\n 'name' = 'MyType',\n 'fields' = [\n 'id' = Type::id()\n ]\n ]));\n }\n} You can also mix-and-match styles for convenience. For example: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass BlogPostType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n 'fields' = [\n 'body' = new ObjectType([\n 'name' = 'BlogPostBody',\n 'fields' = [\n 'html' = Type::string(),\n 'text' = Type::string(),\n ]\n ])\n ]\n ];\n parent::__construct($config);\n }\n}", + "text": "Several styles of type definitions are supported depending on your preferences. Inline definitions: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$myType = new ObjectType([\n 'name' = 'MyType',\n 'fields' = [\n 'id' = Type::id()\n ]\n]); Class per type: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass MyType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n // Note: 'name' is not needed in this form:\n // it will be inferred from class name by omitting namespace and dropping Type suffix\n 'fields' = [\n 'id' = Type::id()\n ]\n ];\n parent::__construct($config);\n }\n} You can also mix-and-match styles for convenience. For example: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\nclass BlogPostType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n 'fields' = [\n 'body' = new ObjectType([\n 'name' = 'BlogPostBody',\n 'fields' = [\n 'html' = Type::string(),\n 'text' = Type::string(),\n ]\n ])\n ]\n ];\n parent::__construct($config);\n }\n}", "title": "Type Definition Styles" }, { "location": "/type-system/#type-registry", - "text": "Every type must be presented in Schema with single instance ( graphql-php \nthrows when it discovers several instances with the same name in schema). Therefore if you define your type as separate PHP class you must ensure that only one \ninstance of that class is added to schema. Typical way to do this is to create registry of your types: ?php\nnamespace MyApp;\n\nclass TypeRegistry\n{\n private $myAType;\n private $myBType;\n\n public function myAType()\n {\n return $this- myAType ?: ($this- myAType = new MyAType($this));\n }\n\n public function myBType()\n {\n return $this- myBType ?: ($this- myBType = new MyBType($this));\n }\n} And use this registry in type definition: ?php\nnamespace MyApp;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\nclass MyAType extends ObjectType\n{\n public function __construct(TypeRegistry $types) \n {\n parent::__construct([\n 'fields' = [\n 'b' = $types- myBType() \n ]\n ]);\n }\n} Obviously you can automate this registry as you wish to reduce boilerplate or even \nintroduce Dependency Injection Container if your types have other dependencies. Alternatively all methods of registry could be static if you prefer - then there is no need\nto pass it in constructor - instead just use use TypeRegistry::myAType() in your type definitions.", + "text": "Every type must be presented in Schema by single instance ( graphql-php \nthrows when it discovers several instances with the same name in schema). Therefore if you define your type as separate PHP class you must ensure that only one \ninstance of that class is added to schema. Typical way to do this is to create registry of your types: ?php\nnamespace MyApp;\n\nclass TypeRegistry\n{\n private $myAType;\n private $myBType;\n\n public function myAType()\n {\n return $this- myAType ?: ($this- myAType = new MyAType($this));\n }\n\n public function myBType()\n {\n return $this- myBType ?: ($this- myBType = new MyBType($this));\n }\n} And use this registry in type definition: ?php\nnamespace MyApp;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\nclass MyAType extends ObjectType\n{\n public function __construct(TypeRegistry $types) \n {\n parent::__construct([\n 'fields' = [\n 'b' = $types- myBType() \n ]\n ]);\n }\n} Obviously you can automate this registry as you wish to reduce boilerplate or even \nintroduce Dependency Injection Container if your types have other dependencies. Alternatively all methods of registry could be static if you prefer - then there is no need\nto pass it in constructor - instead just use use TypeRegistry::myAType() in your type definitions.", "title": "Type Registry" }, { "location": "/type-system/object-types/", - "text": "Object Type Definition\n\n\nObject Type is the most frequently used primitive in typical GraphQL application.\n\n\nConceptually Object Type is a collection of Fields. Each field in turn\nhas it's own type which allows to build complex hierarchies.\n\n\nIn \ngraphql-php\n object type is an instance of \nGraphQL\\Type\\Definition\\ObjectType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Examples\\Blog\\Data\\DataSource;\nuse GraphQL\\Examples\\Blog\\Data\\Story;\n\n$userType = new ObjectType([\n 'name' =\n 'User',\n 'description' =\n 'Our blog visitor',\n 'fields' =\n [\n 'firstName' =\n [\n 'type' =\n Type::string(),\n 'description' =\n 'User first name'\n ],\n 'email' =\n Type::string()\n ]\n]);\n\n$blogStory = new ObjectType([\n 'name' =\n 'Story',\n 'fields' =\n [\n 'body' =\n Type::string(),\n 'author' =\n [\n 'type' =\n $userType,\n 'description' =\n 'Story author',\n 'resolve' =\n function(Story $blogStory) {\n return DataSource::findUser($blogStory-\nauthorId);\n }\n ],\n 'likes' =\n [\n 'type' =\n Type::listOf($userType),\n 'description' =\n 'List of users who liked the story',\n 'args' =\n [\n 'limit' =\n [\n 'type' =\n Type::int(),\n 'description' =\n 'Limit the number of recent likes returned',\n 'defaultValue' =\n 10\n ]\n ],\n 'resolve' =\n function(Story $blogStory, $args) {\n return DataSource::findLikes($blogStory-\nid, $args['limit']);\n }\n ]\n ]\n]);\n\n\n\n\nThis example uses \ninline\n style for Object Type definitions, but there are also \n\nother styles\n (using inheritance or composition).\n\n\nConfiguration options\n\n\nObject type constructor expects configuration array. Below is a full list of available options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Unique name of this object type within Schema\n\n\n\n\n\n\nfields\n\n\narray\n or \ncallback\n returning \narray\n\n\nRequired\n. Array describing object fields. See \nFields\n section below for expected structure of each array entry. See also section on \nCircular types\n for explanation of when to use callback for this option.\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ninterfaces\n\n\narray\n or \ncallback\n returning \narray\n\n\nList of interfaces implemented by this type. See \nInterface Types\n for details. See also section on \nCircular types\n for explanation of when to use callback for this option.\n\n\n\n\n\n\nisTypeOf\n\n\ncallback\n returning \nboolean\n\n\nfunction($value, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Expected to return \ntrue\n if \n$value\n qualifies for this type (see section about \nAbstract Type Resolution\n for explanation).\n\n\n\n\n\n\nresolveField\n\n\ncallback\n returning \nmixed\n\n\nfunction($value, $args, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Given the \n$value\n of this type it is expected to return value for field defined in \n$info-\nfieldName\n. Good place to define type-specific strategy for field resolution. See section on \nData Fetching\n for details.\n\n\n\n\n\n\n\n\nField configuration options\n\n\nBelow is a full list of available field configuration options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the field. When not set - inferred from \nfields\n array key (read about \nshorthand field definition\n below)\n\n\n\n\n\n\ntype\n\n\nType\n\n\nRequired.\n Instance of internal or custom type. Note: type must be represented by single instance within schema (see also \nType Registry\n)\n\n\n\n\n\n\nargs\n\n\narray\n\n\nArray of possible type arguments. Each entry is expected to be an array with keys: \nname\n, \ntype\n, \ndescription\n, \ndefaultValue\n. See \nField Arguments\n section below.\n\n\n\n\n\n\nresolve\n\n\ncallback\n\n\nfunction($value, $args, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Given the \n$value\n of this type it is expected to return value for current field. See section on \nData Fetching\n for details\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this field for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ndeprecationReason\n\n\nstring\n\n\nText describing why this field is deprecated. When not empty - field will not be returned by introspection queries (unless forced)\n\n\n\n\n\n\n\n\nField arguments\n\n\nEvery field on a GraphQL object type can have zero or more arguments, defined in \nargs\n option of field definition.\nEach argument is an array with following options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the argument. When not set - inferred from \nargs\n array key\n\n\n\n\n\n\ntype\n\n\nType\n\n\nRequired.\n Instance of one of \nInput Types\n (\nscalar\n, \nenum\n, \nInputObjectType\n + any combination of those with \nnonNull\n and \nlistOf\n modifiers)\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this argument for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ndefaultValue\n\n\nscalar\n\n\nDefault value for this argument\n\n\n\n\n\n\n\n\nShorthand field definitions\n\n\nFields can be also defined in \nshorthand\n notation (with only \nname\n and \ntype\n options):\n\n\n'fields' =\n [\n 'id' =\n Type::id(),\n 'fieldName' =\n $fieldType\n]\n\n\n\n\nwhich is equivalent of:\n\n\n'fields' =\n [\n 'id' =\n ['type' =\n Type::id()],\n 'fieldName' =\n ['type' =\n $fieldName]\n]\n\n\n\n\nwhich is in turn equivalent of full form:\n\n\n'fields' =\n [\n ['name' =\n 'id', 'type' =\n Type::id()],\n ['name' =\n 'fieldName', 'type' =\n $fieldName]\n]\n\n\n\n\nSame shorthand notation applies to field arguments as well.\n\n\nRecurring and circular types\n\n\nAlmost all real-world applications contain recurring or circular types. \nThink user friends or nested comments for example. \n\n\ngraphql-php\n allows such types, but you have to use \ncallback\n in \noption \nfields\n (and/or \ninterfaces\n).\n\n\nFor example:\n\n\n$userType = null;\n\n$userType = new ObjectType([\n 'name' =\n 'User',\n 'fields' =\n function() use (\n$userType) {\n return [\n 'email' =\n [\n 'type' =\n Type::string()\n ],\n 'friends' =\n [\n 'type' =\n Type::listOf($userType)\n ]\n ];\n }\n]);\n\n\n\n\nSame example for \ninheritance style of type definitions\n using \nTypeRegistry\n:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\nclass UserType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n 'fields' =\n function() {\n return [\n 'email' =\n MyTypes::string(),\n 'friends' =\n MyTypes::listOf(MyTypes::user())\n ];\n }\n ];\n parent::__construct($config);\n }\n}\n\nclass MyTypes \n{\n private static $user;\n\n public static function user()\n {\n return self::$user ?: (self::$user = new UserType());\n }\n\n public static function string()\n {\n return Type::string();\n }\n\n public static function listOf($type)\n {\n return Type::listOf($type);\n }\n}\n\n\n\n\nField Resolution\n\n\nField resolution is the primary mechanism in \ngraphql-php\n for returning actual data for your fields.\nIt is implemented using \nresolveField\n callback in type definition or \nresolve\n\ncallback in field definition (which has precedence).\n\n\nRead section on \nData Fetching\n for complete description of this process.\n\n\nCustom Metadata\n\n\nAll types in \ngraphql-php\n accept configuration array. In some cases you may be interested in \npassing your own metadata for type or field definition.\n\n\ngraphql-php\n preserves original configuration array in every type or field instance in \npublic property \n$config\n. Use it to implement app-level mappings and definitions.", + "text": "Object Type Definition\n\n\nObject Type is the most frequently used primitive in typical GraphQL application.\n\n\nConceptually Object Type is a collection of Fields. Each field in turn\nhas it's own type which allows to build complex hierarchies.\n\n\nIn \ngraphql-php\n object type is an instance of \nGraphQL\\Type\\Definition\\ObjectType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Examples\\Blog\\Data\\DataSource;\nuse GraphQL\\Examples\\Blog\\Data\\Story;\n\n$userType = new ObjectType([\n 'name' =\n 'User',\n 'description' =\n 'Our blog visitor',\n 'fields' =\n [\n 'firstName' =\n [\n 'type' =\n Type::string(),\n 'description' =\n 'User first name'\n ],\n 'email' =\n Type::string()\n ]\n]);\n\n$blogStory = new ObjectType([\n 'name' =\n 'Story',\n 'fields' =\n [\n 'body' =\n Type::string(),\n 'author' =\n [\n 'type' =\n $userType,\n 'description' =\n 'Story author',\n 'resolve' =\n function(Story $blogStory) {\n return DataSource::findUser($blogStory-\nauthorId);\n }\n ],\n 'likes' =\n [\n 'type' =\n Type::listOf($userType),\n 'description' =\n 'List of users who liked the story',\n 'args' =\n [\n 'limit' =\n [\n 'type' =\n Type::int(),\n 'description' =\n 'Limit the number of recent likes returned',\n 'defaultValue' =\n 10\n ]\n ],\n 'resolve' =\n function(Story $blogStory, $args) {\n return DataSource::findLikes($blogStory-\nid, $args['limit']);\n }\n ]\n ]\n]);\n\n\n\n\nThis example uses \ninline\n style for Object Type definitions, but you can also use\n\n\ninheritance\n.\n\n\nConfiguration options\n\n\nObject type constructor expects configuration array. Below is a full list of available options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Unique name of this object type within Schema\n\n\n\n\n\n\nfields\n\n\narray\n or \ncallback\n returning \narray\n\n\nRequired\n. Array describing object fields. See \nFields\n section below for expected structure of each array entry. See also section on \nCircular types\n for explanation of when to use callback for this option.\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ninterfaces\n\n\narray\n or \ncallback\n returning \narray\n\n\nList of interfaces implemented by this type. See \nInterface Types\n for details. See also section on \nCircular types\n for explanation of when to use callback for this option.\n\n\n\n\n\n\nisTypeOf\n\n\ncallback\n returning \nboolean\n\n\nfunction($value, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Expected to return \ntrue\n if \n$value\n qualifies for this type (see section about \nAbstract Type Resolution\n for explanation).\n\n\n\n\n\n\nresolveField\n\n\ncallback\n returning \nmixed\n\n\nfunction($value, $args, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Given the \n$value\n of this type it is expected to return value for field defined in \n$info-\nfieldName\n. Good place to define type-specific strategy for field resolution. See section on \nData Fetching\n for details.\n\n\n\n\n\n\n\n\nField configuration options\n\n\nBelow is a full list of available field configuration options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the field. When not set - inferred from \nfields\n array key (read about \nshorthand field definition\n below)\n\n\n\n\n\n\ntype\n\n\nType\n\n\nRequired.\n Instance of internal or custom type. Note: type must be represented by single instance within schema (see also \nType Registry\n)\n\n\n\n\n\n\nargs\n\n\narray\n\n\nArray of possible type arguments. Each entry is expected to be an array with keys: \nname\n, \ntype\n, \ndescription\n, \ndefaultValue\n. See \nField Arguments\n section below.\n\n\n\n\n\n\nresolve\n\n\ncallback\n\n\nfunction($value, $args, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Given the \n$value\n of this type it is expected to return value for current field. See section on \nData Fetching\n for details\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this field for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ndeprecationReason\n\n\nstring\n\n\nText describing why this field is deprecated. When not empty - field will not be returned by introspection queries (unless forced)\n\n\n\n\n\n\n\n\nField arguments\n\n\nEvery field on a GraphQL object type can have zero or more arguments, defined in \nargs\n option of field definition.\nEach argument is an array with following options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the argument. When not set - inferred from \nargs\n array key\n\n\n\n\n\n\ntype\n\n\nType\n\n\nRequired.\n Instance of one of \nInput Types\n (\nscalar\n, \nenum\n, \nInputObjectType\n + any combination of those with \nnonNull\n and \nlistOf\n modifiers)\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this argument for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ndefaultValue\n\n\nscalar\n\n\nDefault value for this argument\n\n\n\n\n\n\n\n\nShorthand field definitions\n\n\nFields can be also defined in \nshorthand\n notation (with only \nname\n and \ntype\n options):\n\n\n'fields' =\n [\n 'id' =\n Type::id(),\n 'fieldName' =\n $fieldType\n]\n\n\n\n\nwhich is equivalent of:\n\n\n'fields' =\n [\n 'id' =\n ['type' =\n Type::id()],\n 'fieldName' =\n ['type' =\n $fieldName]\n]\n\n\n\n\nwhich is in turn equivalent of full form:\n\n\n'fields' =\n [\n ['name' =\n 'id', 'type' =\n Type::id()],\n ['name' =\n 'fieldName', 'type' =\n $fieldName]\n]\n\n\n\n\nSame shorthand notation applies to field arguments as well.\n\n\nRecurring and circular types\n\n\nAlmost all real-world applications contain recurring or circular types. \nThink user friends or nested comments for example. \n\n\ngraphql-php\n allows such types, but you have to use \ncallback\n in \noption \nfields\n (and/or \ninterfaces\n).\n\n\nFor example:\n\n\n$userType = null;\n\n$userType = new ObjectType([\n 'name' =\n 'User',\n 'fields' =\n function() use (\n$userType) {\n return [\n 'email' =\n [\n 'type' =\n Type::string()\n ],\n 'friends' =\n [\n 'type' =\n Type::listOf($userType)\n ]\n ];\n }\n]);\n\n\n\n\nSame example for \ninheritance style of type definitions\n using \nTypeRegistry\n:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\nclass UserType extends ObjectType\n{\n public function __construct()\n {\n $config = [\n 'fields' =\n function() {\n return [\n 'email' =\n MyTypes::string(),\n 'friends' =\n MyTypes::listOf(MyTypes::user())\n ];\n }\n ];\n parent::__construct($config);\n }\n}\n\nclass MyTypes \n{\n private static $user;\n\n public static function user()\n {\n return self::$user ?: (self::$user = new UserType());\n }\n\n public static function string()\n {\n return Type::string();\n }\n\n public static function listOf($type)\n {\n return Type::listOf($type);\n }\n}\n\n\n\n\nField Resolution\n\n\nField resolution is the primary mechanism in \ngraphql-php\n for returning actual data for your fields.\nIt is implemented using \nresolveField\n callback in type definition or \nresolve\n\ncallback in field definition (which has precedence).\n\n\nRead section on \nData Fetching\n for complete description of this process.\n\n\nCustom Metadata\n\n\nAll types in \ngraphql-php\n accept configuration array. In some cases you may be interested in \npassing your own metadata for type or field definition.\n\n\ngraphql-php\n preserves original configuration array in every type or field instance in \npublic property \n$config\n. Use it to implement app-level mappings and definitions.", "title": "Object Types" }, { "location": "/type-system/object-types/#object-type-definition", - "text": "Object Type is the most frequently used primitive in typical GraphQL application. Conceptually Object Type is a collection of Fields. Each field in turn\nhas it's own type which allows to build complex hierarchies. In graphql-php object type is an instance of GraphQL\\Type\\Definition\\ObjectType \n(or one of it subclasses) which accepts configuration array in constructor: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Examples\\Blog\\Data\\DataSource;\nuse GraphQL\\Examples\\Blog\\Data\\Story;\n\n$userType = new ObjectType([\n 'name' = 'User',\n 'description' = 'Our blog visitor',\n 'fields' = [\n 'firstName' = [\n 'type' = Type::string(),\n 'description' = 'User first name'\n ],\n 'email' = Type::string()\n ]\n]);\n\n$blogStory = new ObjectType([\n 'name' = 'Story',\n 'fields' = [\n 'body' = Type::string(),\n 'author' = [\n 'type' = $userType,\n 'description' = 'Story author',\n 'resolve' = function(Story $blogStory) {\n return DataSource::findUser($blogStory- authorId);\n }\n ],\n 'likes' = [\n 'type' = Type::listOf($userType),\n 'description' = 'List of users who liked the story',\n 'args' = [\n 'limit' = [\n 'type' = Type::int(),\n 'description' = 'Limit the number of recent likes returned',\n 'defaultValue' = 10\n ]\n ],\n 'resolve' = function(Story $blogStory, $args) {\n return DataSource::findLikes($blogStory- id, $args['limit']);\n }\n ]\n ]\n]); This example uses inline style for Object Type definitions, but there are also other styles (using inheritance or composition).", + "text": "Object Type is the most frequently used primitive in typical GraphQL application. Conceptually Object Type is a collection of Fields. Each field in turn\nhas it's own type which allows to build complex hierarchies. In graphql-php object type is an instance of GraphQL\\Type\\Definition\\ObjectType \n(or one of it subclasses) which accepts configuration array in constructor: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Examples\\Blog\\Data\\DataSource;\nuse GraphQL\\Examples\\Blog\\Data\\Story;\n\n$userType = new ObjectType([\n 'name' = 'User',\n 'description' = 'Our blog visitor',\n 'fields' = [\n 'firstName' = [\n 'type' = Type::string(),\n 'description' = 'User first name'\n ],\n 'email' = Type::string()\n ]\n]);\n\n$blogStory = new ObjectType([\n 'name' = 'Story',\n 'fields' = [\n 'body' = Type::string(),\n 'author' = [\n 'type' = $userType,\n 'description' = 'Story author',\n 'resolve' = function(Story $blogStory) {\n return DataSource::findUser($blogStory- authorId);\n }\n ],\n 'likes' = [\n 'type' = Type::listOf($userType),\n 'description' = 'List of users who liked the story',\n 'args' = [\n 'limit' = [\n 'type' = Type::int(),\n 'description' = 'Limit the number of recent likes returned',\n 'defaultValue' = 10\n ]\n ],\n 'resolve' = function(Story $blogStory, $args) {\n return DataSource::findLikes($blogStory- id, $args['limit']);\n }\n ]\n ]\n]); This example uses inline style for Object Type definitions, but you can also use inheritance .", "title": "Object Type Definition" }, { @@ -117,7 +127,7 @@ }, { "location": "/type-system/scalar-types/", - "text": "Built-in Scalar Types\n\n\nGraphQL specification describes several built-in scalar types. In \ngraphql-php\n they are \nexposed as static methods of \nGraphQL\\Type\\Definition\\Type\n class:\n\n\nuse GraphQL\\Type\\Definition\\Type;\n\n// Built-in Scalar types:\nType::string(); // String type\nType::int(); // Int type\nType::float(); // Float type\nType::boolean(); // Boolean type\nType::id(); // ID type\n\n\n\n\nThose methods return instances of \nGraphQL\\Type\\Definition\\ScalarType\n (actually one of it subclasses).\nUse them directly in type definitions, or wrap in your \nTypeRegistry\n \n(if you use one).\n\n\nWriting Custom Scalar Types\n\n\nIn addition to built-in scalars, you can define your own scalar types with additional validation. \nTypical examples of such types are: \nEmail\n, \nDate\n, \nUrl\n, etc.\n\n\nIn order to implement your own type you must understand how scalars are presented in GraphQL.\nGraphQL deals with scalars in following cases:\n\n\n\n\n\n\nWhen converting \ninternal representation\n of value returned by your app (e.g. stored in database \nor hardcoded in source code) to \nserialized\n representation included in response.\n\n\n\n\n\n\nWhen converting \ninput value\n passed by client in variables along with GraphQL query to \n\ninternal representation\n of your app.\n\n\n\n\n\n\nWhen converting \ninput literal value\n hardcoded in GraphQL query (e.g. field argument value) to \n\ninternal representation\n of your app.\n\n\n\n\n\n\nThose cases are covered by methods \nserialize\n, \nparseValue\n and \nparseLiteral\n of abstract \nScalarType\n \nclass respectively.\n\n\nHere is an example of simple \nEmail\n type (using inheritance):\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Error\\Error;\nuse GraphQL\\Language\\AST\\StringValue;\nuse GraphQL\\Type\\Definition\\ScalarType;\nuse GraphQL\\Utils;\n\nclass EmailType extends ScalarType\n{\n // Note: name can be omitted. In this case it will be inferred from class name \n // (suffix \nType\n will be dropped)\n public $name = 'Email';\n\n /**\n * Serializes an internal value to include in a response.\n *\n * @param string $value\n * @return string\n */\n public function serialize($value)\n {\n // Assuming internal representation of email is always correct:\n return $value;\n\n // If it might be incorrect and you want to make sure that only correct values are included in response -\n // use following line instead:\n // return $this-\nparseValue($value);\n }\n\n /**\n * Parses an externally provided value (query variable) to use as an input\n *\n * @param mixed $value\n * @return mixed\n */\n public function parseValue($value)\n {\n if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {\n throw new \\UnexpectedValueException(\nCannot represent value as email: \n . Utils::printSafe($value));\n }\n return $value;\n }\n\n /**\n * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.\n * \n * E.g. \n * {\n * user(email: \nuser@example.com\n) \n * }\n *\n * @param \\GraphQL\\Language\\AST\\Node $valueAST\n * @return string\n * @throws Error\n */\n public function parseLiteral($valueAST)\n {\n // Note: throwing GraphQL\\Error\\Error vs \\UnexpectedValueException to benefit from GraphQL\n // error location in query:\n if (!$valueAST instanceof StringValue) {\n throw new Error('Query error: Can only parse strings got: ' . $valueAST-\nkind, [$valueAST]);\n }\n if (!filter_var($valueAST-\nvalue, FILTER_VALIDATE_EMAIL)) {\n throw new Error(\nNot a valid email\n, [$valueAST]);\n }\n return $valueAST-\nvalue;\n }\n}\n\n\n\n\nSame example, using composition over inheritance:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\DefinitionContainer;\nuse GraphQL\\Type\\Definition\\CustomScalarType;\n\nclass EmailType implements DefinitionContainer\n{\n private $definition;\n\n public function getDefinition()\n {\n return $this-\ndefinition ?: ($this-\ndefinition = new CustomScalarType([\n 'name' =\n 'Email',\n 'serialize' =\n function($value) {/* See function body above */},\n 'parseValue' =\n function($value) {/* See function body above */},\n 'parseLiteral' =\n function($valueAST) {/* See function body above */},\n ]));\n }\n}\n\n\n\n\nOr with inline style:\n\n\n?php\nuse GraphQL\\Type\\Definition\\CustomScalarType;\n\n$emailType = new CustomScalarType([\n 'name' =\n 'Email',\n 'serialize' =\n function($value) {/* See function body above */},\n 'parseValue' =\n function($value) {/* See function body above */},\n 'parseLiteral' =\n function($valueAST) {/* See function body above */},\n]);", + "text": "Built-in Scalar Types\n\n\nGraphQL specification describes several built-in scalar types. In \ngraphql-php\n they are \nexposed as static methods of \nGraphQL\\Type\\Definition\\Type\n class:\n\n\nuse GraphQL\\Type\\Definition\\Type;\n\n// Built-in Scalar types:\nType::string(); // String type\nType::int(); // Int type\nType::float(); // Float type\nType::boolean(); // Boolean type\nType::id(); // ID type\n\n\n\n\nThose methods return instances of \nGraphQL\\Type\\Definition\\ScalarType\n (actually one of it subclasses).\nUse them directly in type definitions, or wrap in your \nTypeRegistry\n \n(if you use one).\n\n\nWriting Custom Scalar Types\n\n\nIn addition to built-in scalars, you can define your own scalar types with additional validation. \nTypical examples of such types are: \nEmail\n, \nDate\n, \nUrl\n, etc.\n\n\nIn order to implement your own type you must understand how scalars are presented in GraphQL.\nGraphQL deals with scalars in following cases:\n\n\n\n\n\n\nWhen converting \ninternal representation\n of value returned by your app (e.g. stored in database \nor hardcoded in source code) to \nserialized\n representation included in response.\n\n\n\n\n\n\nWhen converting \ninput value\n passed by client in variables along with GraphQL query to \n\ninternal representation\n of your app.\n\n\n\n\n\n\nWhen converting \ninput literal value\n hardcoded in GraphQL query (e.g. field argument value) to \n\ninternal representation\n of your app.\n\n\n\n\n\n\nThose cases are covered by methods \nserialize\n, \nparseValue\n and \nparseLiteral\n of abstract \nScalarType\n \nclass respectively.\n\n\nHere is an example of simple \nEmail\n type:\n\n\n?php\nnamespace MyApp;\n\nuse GraphQL\\Error\\Error;\nuse GraphQL\\Language\\AST\\StringValueNode;\nuse GraphQL\\Type\\Definition\\ScalarType;\nuse GraphQL\\Utils;\n\nclass EmailType extends ScalarType\n{\n // Note: name can be omitted. In this case it will be inferred from class name \n // (suffix \nType\n will be dropped)\n public $name = 'Email';\n\n /**\n * Serializes an internal value to include in a response.\n *\n * @param string $value\n * @return string\n */\n public function serialize($value)\n {\n // Assuming internal representation of email is always correct:\n return $value;\n\n // If it might be incorrect and you want to make sure that only correct values are included in response -\n // use following line instead:\n // return $this-\nparseValue($value);\n }\n\n /**\n * Parses an externally provided value (query variable) to use as an input\n *\n * @param mixed $value\n * @return mixed\n */\n public function parseValue($value)\n {\n if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {\n throw new \\UnexpectedValueException(\nCannot represent value as email: \n . Utils::printSafe($value));\n }\n return $value;\n }\n\n /**\n * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.\n * \n * E.g. \n * {\n * user(email: \nuser@example.com\n) \n * }\n *\n * @param \\GraphQL\\Language\\AST\\Node $valueNode\n * @return string\n * @throws Error\n */\n public function parseLiteral($valueNode)\n {\n // Note: throwing GraphQL\\Error\\Error vs \\UnexpectedValueException to benefit from GraphQL\n // error location in query:\n if (!$valueNode instanceof StringValueNode) {\n throw new Error('Query error: Can only parse strings got: ' . $valueNode-\nkind, [$valueNode]);\n }\n if (!filter_var($valueNode-\nvalue, FILTER_VALIDATE_EMAIL)) {\n throw new Error(\nNot a valid email\n, [$valueNode]);\n }\n return $valueNode-\nvalue;\n }\n}\n\n\n\n\nOr with inline style:\n\n\n?php\nuse GraphQL\\Type\\Definition\\CustomScalarType;\n\n$emailType = new CustomScalarType([\n 'name' =\n 'Email',\n 'serialize' =\n function($value) {/* See function body above */},\n 'parseValue' =\n function($value) {/* See function body above */},\n 'parseLiteral' =\n function($valueNode) {/* See function body above */},\n]);", "title": "Scalar Types" }, { @@ -127,17 +137,17 @@ }, { "location": "/type-system/scalar-types/#writing-custom-scalar-types", - "text": "In addition to built-in scalars, you can define your own scalar types with additional validation. \nTypical examples of such types are: Email , Date , Url , etc. In order to implement your own type you must understand how scalars are presented in GraphQL.\nGraphQL deals with scalars in following cases: When converting internal representation of value returned by your app (e.g. stored in database \nor hardcoded in source code) to serialized representation included in response. When converting input value passed by client in variables along with GraphQL query to internal representation of your app. When converting input literal value hardcoded in GraphQL query (e.g. field argument value) to internal representation of your app. Those cases are covered by methods serialize , parseValue and parseLiteral of abstract ScalarType \nclass respectively. Here is an example of simple Email type (using inheritance): ?php\nnamespace MyApp;\n\nuse GraphQL\\Error\\Error;\nuse GraphQL\\Language\\AST\\StringValue;\nuse GraphQL\\Type\\Definition\\ScalarType;\nuse GraphQL\\Utils;\n\nclass EmailType extends ScalarType\n{\n // Note: name can be omitted. In this case it will be inferred from class name \n // (suffix Type will be dropped)\n public $name = 'Email';\n\n /**\n * Serializes an internal value to include in a response.\n *\n * @param string $value\n * @return string\n */\n public function serialize($value)\n {\n // Assuming internal representation of email is always correct:\n return $value;\n\n // If it might be incorrect and you want to make sure that only correct values are included in response -\n // use following line instead:\n // return $this- parseValue($value);\n }\n\n /**\n * Parses an externally provided value (query variable) to use as an input\n *\n * @param mixed $value\n * @return mixed\n */\n public function parseValue($value)\n {\n if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {\n throw new \\UnexpectedValueException( Cannot represent value as email: . Utils::printSafe($value));\n }\n return $value;\n }\n\n /**\n * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.\n * \n * E.g. \n * {\n * user(email: user@example.com ) \n * }\n *\n * @param \\GraphQL\\Language\\AST\\Node $valueAST\n * @return string\n * @throws Error\n */\n public function parseLiteral($valueAST)\n {\n // Note: throwing GraphQL\\Error\\Error vs \\UnexpectedValueException to benefit from GraphQL\n // error location in query:\n if (!$valueAST instanceof StringValue) {\n throw new Error('Query error: Can only parse strings got: ' . $valueAST- kind, [$valueAST]);\n }\n if (!filter_var($valueAST- value, FILTER_VALIDATE_EMAIL)) {\n throw new Error( Not a valid email , [$valueAST]);\n }\n return $valueAST- value;\n }\n} Same example, using composition over inheritance: ?php\nnamespace MyApp;\n\nuse GraphQL\\Type\\DefinitionContainer;\nuse GraphQL\\Type\\Definition\\CustomScalarType;\n\nclass EmailType implements DefinitionContainer\n{\n private $definition;\n\n public function getDefinition()\n {\n return $this- definition ?: ($this- definition = new CustomScalarType([\n 'name' = 'Email',\n 'serialize' = function($value) {/* See function body above */},\n 'parseValue' = function($value) {/* See function body above */},\n 'parseLiteral' = function($valueAST) {/* See function body above */},\n ]));\n }\n} Or with inline style: ?php\nuse GraphQL\\Type\\Definition\\CustomScalarType;\n\n$emailType = new CustomScalarType([\n 'name' = 'Email',\n 'serialize' = function($value) {/* See function body above */},\n 'parseValue' = function($value) {/* See function body above */},\n 'parseLiteral' = function($valueAST) {/* See function body above */},\n]);", + "text": "In addition to built-in scalars, you can define your own scalar types with additional validation. \nTypical examples of such types are: Email , Date , Url , etc. In order to implement your own type you must understand how scalars are presented in GraphQL.\nGraphQL deals with scalars in following cases: When converting internal representation of value returned by your app (e.g. stored in database \nor hardcoded in source code) to serialized representation included in response. When converting input value passed by client in variables along with GraphQL query to internal representation of your app. When converting input literal value hardcoded in GraphQL query (e.g. field argument value) to internal representation of your app. Those cases are covered by methods serialize , parseValue and parseLiteral of abstract ScalarType \nclass respectively. Here is an example of simple Email type: ?php\nnamespace MyApp;\n\nuse GraphQL\\Error\\Error;\nuse GraphQL\\Language\\AST\\StringValueNode;\nuse GraphQL\\Type\\Definition\\ScalarType;\nuse GraphQL\\Utils;\n\nclass EmailType extends ScalarType\n{\n // Note: name can be omitted. In this case it will be inferred from class name \n // (suffix Type will be dropped)\n public $name = 'Email';\n\n /**\n * Serializes an internal value to include in a response.\n *\n * @param string $value\n * @return string\n */\n public function serialize($value)\n {\n // Assuming internal representation of email is always correct:\n return $value;\n\n // If it might be incorrect and you want to make sure that only correct values are included in response -\n // use following line instead:\n // return $this- parseValue($value);\n }\n\n /**\n * Parses an externally provided value (query variable) to use as an input\n *\n * @param mixed $value\n * @return mixed\n */\n public function parseValue($value)\n {\n if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {\n throw new \\UnexpectedValueException( Cannot represent value as email: . Utils::printSafe($value));\n }\n return $value;\n }\n\n /**\n * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.\n * \n * E.g. \n * {\n * user(email: user@example.com ) \n * }\n *\n * @param \\GraphQL\\Language\\AST\\Node $valueNode\n * @return string\n * @throws Error\n */\n public function parseLiteral($valueNode)\n {\n // Note: throwing GraphQL\\Error\\Error vs \\UnexpectedValueException to benefit from GraphQL\n // error location in query:\n if (!$valueNode instanceof StringValueNode) {\n throw new Error('Query error: Can only parse strings got: ' . $valueNode- kind, [$valueNode]);\n }\n if (!filter_var($valueNode- value, FILTER_VALIDATE_EMAIL)) {\n throw new Error( Not a valid email , [$valueNode]);\n }\n return $valueNode- value;\n }\n} Or with inline style: ?php\nuse GraphQL\\Type\\Definition\\CustomScalarType;\n\n$emailType = new CustomScalarType([\n 'name' = 'Email',\n 'serialize' = function($value) {/* See function body above */},\n 'parseValue' = function($value) {/* See function body above */},\n 'parseLiteral' = function($valueNode) {/* See function body above */},\n]);", "title": "Writing Custom Scalar Types" }, { "location": "/type-system/enum-types/", - "text": "Enum Type Definition\n\n\nEnumeration types are a special kind of scalar that is restricted to a particular set \nof allowed values. \n\n\nIn \ngraphql-php\n enum type is an instance of \nGraphQL\\Type\\Definition\\EnumType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\nuse GraphQL\\Type\\Definition\\EnumType;\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n [\n 'value' =\n 4,\n 'description' =\n 'Released in 1977.'\n ],\n 'EMPIRE' =\n [\n 'value' =\n 5,\n 'description' =\n 'Released in 1980.'\n ],\n 'JEDI' =\n [\n 'value' =\n 6,\n 'description' =\n 'Released in 1983.'\n ],\n ]\n]);\n\n\n\n\nThis example uses \ninline\n style for Enum Type definition, but there are also \n\nother styles\n (using inheritance or composition).\n\n\nConfiguration options\n\n\nEnum Type constructor accepts array with following options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the type. When not set - inferred from array key (read about \nshorthand field definition\n below)\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of the type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\nvalues\n\n\narray\n\n\nList of enumerated items, see below for expected structure of each entry\n\n\n\n\n\n\n\n\nEach entry of \nvalues\n array in turn accepts following options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the item. When not set - inferred from array key (read about \nshorthand field definition\n below)\n\n\n\n\n\n\nvalue\n\n\nmixed\n\n\nInternal representation of enum item in your application (could be any value, including complex objects or callbacks)\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of enum value for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ndeprecationReason\n\n\nstring\n\n\nText describing why this enum value is deprecated. When not empty - item will not be returned by introspection queries (unless forced)\n\n\n\n\n\n\n\n\nShorthand definitions\n\n\nIf internal representation of enumerated item is the same as item name, then you can use\nfollowing shorthand for definition:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n ['NEWHOPE', 'EMPIRE', 'JEDI']\n]);\n\n\n\n\nwhich is equivalent of:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n 'NEWHOPE', \n 'EMPIRE' =\n 'EMPIRE', \n 'JEDI' =\n 'JEDI'\n ]\n]);\n\n\n\n\nwhich is in turn equivalent of:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n ['value' =\n 'NEWHOPE'], \n 'EMPIRE' =\n ['value' =\n 'EMPIRE'], \n 'JEDI' =\n ['value' =\n 'JEDI']\n ]\n]);\n\n\n\n\nwhich is in turn equivalent of full form:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n ['name' =\n 'NEWHOPE', 'value' =\n 'NEWHOPE'], \n ['name' =\n 'EMPIRE', 'value' =\n 'EMPIRE'], \n ['name' =\n 'JEDI', 'value' =\n 'JEDI']\n ]\n]);\n\n\n\n\nField Resolution\n\n\nWhen object field is of Enum Type, field resolver is expected to return internal \nrepresentation of corresponding Enum item (\nvalue\n in config). \ngraphql-php\n will \nthen serialize this \nvalue\n to \nname\n to include in response:\n\n\nuse GraphQL\\Type\\Definition\\EnumType;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n [\n 'value' =\n 4,\n 'description' =\n 'Released in 1977.'\n ],\n 'EMPIRE' =\n [\n 'value' =\n 5,\n 'description' =\n 'Released in 1980.'\n ],\n 'JEDI' =\n [\n 'value' =\n 6,\n 'description' =\n 'Released in 1983.'\n ],\n ]\n]);\n\n$heroType = new ObjectType([\n 'name' =\n 'Hero',\n 'fields' =\n [\n 'appearsIn' =\n [\n 'type' =\n $episodeEnum,\n 'resolve' =\n function() {\n return 5; // Actual entry in response will be 'appearsIn' =\n 'EMPIRE'\n }\n ]\n ]\n])\n\n\n\n\nReverse is true when enum is used as input type (e.g. as field argument). \nGraphQL will treat enum input as \nname\n and convert it into \nvalue\n before passing to your app.\n\n\nFor example, given object type definition:\n\n\n$heroType = new ObjectType([\n 'name' =\n 'Hero',\n 'fields' =\n [\n 'appearsIn' =\n [\n 'type' =\n Type::boolean(),\n 'args' =\n [\n 'episode' =\n Type::nonNull($enumType)\n ]\n 'resolve' =\n function($_value, $args) {\n return $args['episode'] === 5 ? true : false; \n }\n ]\n ]\n])\n\n\n\n\nThen following query:\n\n\nfragment on Hero {\n appearsInNewHope: appearsIn(NEWHOPE)\n appearsInEmpire: appearsIn(EMPIRE)\n}\n\n\n\n\nwill return:\n\n\n[\n 'appearsInNewHope' =\n false,\n 'appearsInEmpire' =\n true\n]", + "text": "Enum Type Definition\n\n\nEnumeration types are a special kind of scalar that is restricted to a particular set \nof allowed values. \n\n\nIn \ngraphql-php\n enum type is an instance of \nGraphQL\\Type\\Definition\\EnumType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\nuse GraphQL\\Type\\Definition\\EnumType;\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n [\n 'value' =\n 4,\n 'description' =\n 'Released in 1977.'\n ],\n 'EMPIRE' =\n [\n 'value' =\n 5,\n 'description' =\n 'Released in 1980.'\n ],\n 'JEDI' =\n [\n 'value' =\n 6,\n 'description' =\n 'Released in 1983.'\n ],\n ]\n]);\n\n\n\n\nThis example uses \ninline\n style for Enum Type definition, but you can also use\n\ninheritance\n.\n\n\nConfiguration options\n\n\nEnum Type constructor accepts array with following options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the type. When not set - inferred from array key (read about \nshorthand field definition\n below)\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of the type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\nvalues\n\n\narray\n\n\nList of enumerated items, see below for expected structure of each entry\n\n\n\n\n\n\n\n\nEach entry of \nvalues\n array in turn accepts following options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Name of the item. When not set - inferred from array key (read about \nshorthand field definition\n below)\n\n\n\n\n\n\nvalue\n\n\nmixed\n\n\nInternal representation of enum item in your application (could be any value, including complex objects or callbacks)\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of enum value for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\ndeprecationReason\n\n\nstring\n\n\nText describing why this enum value is deprecated. When not empty - item will not be returned by introspection queries (unless forced)\n\n\n\n\n\n\n\n\nShorthand definitions\n\n\nIf internal representation of enumerated item is the same as item name, then you can use\nfollowing shorthand for definition:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n ['NEWHOPE', 'EMPIRE', 'JEDI']\n]);\n\n\n\n\nwhich is equivalent of:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n 'NEWHOPE', \n 'EMPIRE' =\n 'EMPIRE', \n 'JEDI' =\n 'JEDI'\n ]\n]);\n\n\n\n\nwhich is in turn equivalent of:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n ['value' =\n 'NEWHOPE'], \n 'EMPIRE' =\n ['value' =\n 'EMPIRE'], \n 'JEDI' =\n ['value' =\n 'JEDI']\n ]\n]);\n\n\n\n\nwhich is in turn equivalent of full form:\n\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n ['name' =\n 'NEWHOPE', 'value' =\n 'NEWHOPE'], \n ['name' =\n 'EMPIRE', 'value' =\n 'EMPIRE'], \n ['name' =\n 'JEDI', 'value' =\n 'JEDI']\n ]\n]);\n\n\n\n\nField Resolution\n\n\nWhen object field is of Enum Type, field resolver is expected to return internal \nrepresentation of corresponding Enum item (\nvalue\n in config). \ngraphql-php\n will \nthen serialize this \nvalue\n to \nname\n to include in response:\n\n\nuse GraphQL\\Type\\Definition\\EnumType;\nuse GraphQL\\Type\\Definition\\ObjectType;\n\n$episodeEnum = new EnumType([\n 'name' =\n 'Episode',\n 'description' =\n 'One of the films in the Star Wars Trilogy',\n 'values' =\n [\n 'NEWHOPE' =\n [\n 'value' =\n 4,\n 'description' =\n 'Released in 1977.'\n ],\n 'EMPIRE' =\n [\n 'value' =\n 5,\n 'description' =\n 'Released in 1980.'\n ],\n 'JEDI' =\n [\n 'value' =\n 6,\n 'description' =\n 'Released in 1983.'\n ],\n ]\n]);\n\n$heroType = new ObjectType([\n 'name' =\n 'Hero',\n 'fields' =\n [\n 'appearsIn' =\n [\n 'type' =\n $episodeEnum,\n 'resolve' =\n function() {\n return 5; // Actual entry in response will be 'appearsIn' =\n 'EMPIRE'\n }\n ]\n ]\n])\n\n\n\n\nReverse is true when enum is used as input type (e.g. as field argument). \nGraphQL will treat enum input as \nname\n and convert it into \nvalue\n before passing to your app.\n\n\nFor example, given object type definition:\n\n\n$heroType = new ObjectType([\n 'name' =\n 'Hero',\n 'fields' =\n [\n 'appearsIn' =\n [\n 'type' =\n Type::boolean(),\n 'args' =\n [\n 'episode' =\n Type::nonNull($enumType)\n ]\n 'resolve' =\n function($_value, $args) {\n return $args['episode'] === 5 ? true : false; \n }\n ]\n ]\n])\n\n\n\n\nThen following query:\n\n\nfragment on Hero {\n appearsInNewHope: appearsIn(NEWHOPE)\n appearsInEmpire: appearsIn(EMPIRE)\n}\n\n\n\n\nwill return:\n\n\n[\n 'appearsInNewHope' =\n false,\n 'appearsInEmpire' =\n true\n]", "title": "Enumeration Types" }, { "location": "/type-system/enum-types/#enum-type-definition", - "text": "Enumeration types are a special kind of scalar that is restricted to a particular set \nof allowed values. In graphql-php enum type is an instance of GraphQL\\Type\\Definition\\EnumType \n(or one of it subclasses) which accepts configuration array in constructor: use GraphQL\\Type\\Definition\\EnumType;\n\n$episodeEnum = new EnumType([\n 'name' = 'Episode',\n 'description' = 'One of the films in the Star Wars Trilogy',\n 'values' = [\n 'NEWHOPE' = [\n 'value' = 4,\n 'description' = 'Released in 1977.'\n ],\n 'EMPIRE' = [\n 'value' = 5,\n 'description' = 'Released in 1980.'\n ],\n 'JEDI' = [\n 'value' = 6,\n 'description' = 'Released in 1983.'\n ],\n ]\n]); This example uses inline style for Enum Type definition, but there are also other styles (using inheritance or composition).", + "text": "Enumeration types are a special kind of scalar that is restricted to a particular set \nof allowed values. In graphql-php enum type is an instance of GraphQL\\Type\\Definition\\EnumType \n(or one of it subclasses) which accepts configuration array in constructor: use GraphQL\\Type\\Definition\\EnumType;\n\n$episodeEnum = new EnumType([\n 'name' = 'Episode',\n 'description' = 'One of the films in the Star Wars Trilogy',\n 'values' = [\n 'NEWHOPE' = [\n 'value' = 4,\n 'description' = 'Released in 1977.'\n ],\n 'EMPIRE' = [\n 'value' = 5,\n 'description' = 'Released in 1980.'\n ],\n 'JEDI' = [\n 'value' = 6,\n 'description' = 'Released in 1983.'\n ],\n ]\n]); This example uses inline style for Enum Type definition, but you can also use inheritance .", "title": "Enum Type Definition" }, { @@ -172,12 +182,12 @@ }, { "location": "/type-system/interfaces/", - "text": "Interface Type Definition\n\n\nAn Interface is an abstract type that includes a certain set of fields that a \ntype must include to implement the interface.\n\n\nIn \ngraphql-php\n interface type is an instance of \nGraphQL\\Type\\Definition\\InterfaceType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\nuse GraphQL\\Type\\Definition\\InterfaceType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$character = new InterfaceType([\n 'name' =\n 'Character',\n 'description' =\n 'A character in the Star Wars Trilogy',\n 'fields' =\n [\n 'id' =\n [\n 'type' =\n Type::nonNull(Type::string()),\n 'description' =\n 'The id of the character.',\n ],\n 'name' =\n [\n 'type' =\n Type::string(),\n 'description' =\n 'The name of the character.'\n ]\n ],\n 'resolveType' =\n function ($value) {\n if ($value-\ntype === 'human') {\n return MyTypes::human(); \n } else {\n return MyTypes::droid();\n }\n }\n]);\n\n\n\n\nThis example uses \ninline\n style for Interface definition, but there are also \n\nother styles\n (using inheritance or composition).\n\n\nConfiguration options\n\n\nConstructor of InterfaceType accepts an array. Below is a full list of allowed options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Unique name of this interface type within Schema\n\n\n\n\n\n\nfields\n\n\narray\n\n\nRequired.\n List of fields required to be defined by interface implementors. Same as \nFields for Object Type\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\nresolveType\n\n\ncallback\n returning instance of \nObjectType\n\n\nfunction($value, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Any \ncallable\n that receives \n$value\n from resolver of the parent field and returns concrete interface implementor for that \n$value\n.\n\n\n\n\n\n\n\n\nImplementing interface\n\n\nTo implement the Interface simply add it to \ninterfaces\n array of Object Type definition:\n\n\n$humanType = new ObjectType([\n 'name' =\n 'Human',\n 'fields' =\n [\n 'id' =\n [\n 'type' =\n Type::nonNull(Type::string()),\n 'description' =\n 'The id of the character.',\n ],\n 'name' =\n [\n 'type' =\n Type::string(),\n 'description' =\n 'The name of the character.'\n ]\n ],\n 'interfaces' =\n [\n $character\n ]\n]);\n\n\n\n\nNote that Object Type must include all fields of interface with exact same types \n(including \nnonNull\n specification) and arguments.\n\n\nThe only exception is when object's field type is more specific than the type of this field defined in interface \n(see \nCovariant return types for interface fields\n below)\n\n\nCovariant return types for interface fields\n\n\nObject types implementing interface may change field type to more specific.\nExample:\n\n\ninterface A {\n field1: A\n}\n\ntype B implements A {\n field1: B\n}\n\n\n\n\nSharing Interface fields\n\n\nSince every Object Type implementing an Interface must have the same set of fields - it often makes \nsense to re-use field definitions of Interface in Object Types:\n\n\n$humanType = new ObjectType([\n 'name' =\n 'Human',\n 'interfaces' =\n [\n $character\n ],\n 'fields' =\n [\n 'height' =\n Type::float(),\n $character-\ngetField('id'),\n $character-\ngetField('name')\n ] \n]);\n\n\n\n\nIn this case field definitions are created only once (as a part of Interface Type) and then \nre-used by all interface implementors. It can save several microseconds and kilobytes + ensures that \nfield definitions of Interface and implementors are always in sync.\n\n\nYet it creates a problem with resolution of such fields. There are two ways how shared fields could \nbe resolved:\n\n\n\n\n\n\nIf field resolution algorithm is the same for all Interface implementors - you can simply add \n\nresolve\n option to field definition in Interface itself.\n\n\n\n\n\n\nIf field resolution varies from implementor to implementor - you can specify \nresolveField\n \noption in \nObject Type config\n and handle field \nresolutions there \n(Note: \nresolve\n option in field definition has precedence over \nresolveField\n option in object type definition)\n\n\n\n\n\n\nInterface role in data fetching\n\n\nThe only responsibility of interface in Data Fetching process is to return concrete Object Type \nfor given \n$value\n in \nresolveType\n. Then resolution of fields is delegated to resolvers of this \nconcrete Object Type.\n\n\nIf \nresolveType\n option is omitted, \ngraphql-php\n will loop through all interface implementors and \nuse their \nisTypeOf\n callback to pick the first suitable one. This is obviously less efficient \nthan single \nresolveType\n call. So it is recommended to define \nresolveType\n whenever possible.", + "text": "Interface Type Definition\n\n\nAn Interface is an abstract type that includes a certain set of fields that a \ntype must include to implement the interface.\n\n\nIn \ngraphql-php\n interface type is an instance of \nGraphQL\\Type\\Definition\\InterfaceType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\nuse GraphQL\\Type\\Definition\\InterfaceType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$character = new InterfaceType([\n 'name' =\n 'Character',\n 'description' =\n 'A character in the Star Wars Trilogy',\n 'fields' =\n [\n 'id' =\n [\n 'type' =\n Type::nonNull(Type::string()),\n 'description' =\n 'The id of the character.',\n ],\n 'name' =\n [\n 'type' =\n Type::string(),\n 'description' =\n 'The name of the character.'\n ]\n ],\n 'resolveType' =\n function ($value) {\n if ($value-\ntype === 'human') {\n return MyTypes::human(); \n } else {\n return MyTypes::droid();\n }\n }\n]);\n\n\n\n\nThis example uses \ninline\n style for Interface definition, but you can also use\n\n\ninheritance\n.\n\n\nConfiguration options\n\n\nConstructor of InterfaceType accepts an array. Below is a full list of allowed options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Unique name of this interface type within Schema\n\n\n\n\n\n\nfields\n\n\narray\n\n\nRequired.\n List of fields required to be defined by interface implementors. Same as \nFields for Object Type\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\nresolveType\n\n\ncallback\n returning instance of \nObjectType\n\n\nfunction($value, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Any \ncallable\n that receives \n$value\n from resolver of the parent field and returns concrete interface implementor for that \n$value\n.\n\n\n\n\n\n\n\n\nImplementing interface\n\n\nTo implement the Interface simply add it to \ninterfaces\n array of Object Type definition:\n\n\n$humanType = new ObjectType([\n 'name' =\n 'Human',\n 'fields' =\n [\n 'id' =\n [\n 'type' =\n Type::nonNull(Type::string()),\n 'description' =\n 'The id of the character.',\n ],\n 'name' =\n [\n 'type' =\n Type::string(),\n 'description' =\n 'The name of the character.'\n ]\n ],\n 'interfaces' =\n [\n $character\n ]\n]);\n\n\n\n\nNote that Object Type must include all fields of interface with exact same types \n(including \nnonNull\n specification) and arguments.\n\n\nThe only exception is when object's field type is more specific than the type of this field defined in interface \n(see \nCovariant return types for interface fields\n below)\n\n\nCovariant return types for interface fields\n\n\nObject types implementing interface may change field type to more specific.\nExample:\n\n\ninterface A {\n field1: A\n}\n\ntype B implements A {\n field1: B\n}\n\n\n\n\nSharing Interface fields\n\n\nSince every Object Type implementing an Interface must have the same set of fields - it often makes \nsense to re-use field definitions of Interface in Object Types:\n\n\n$humanType = new ObjectType([\n 'name' =\n 'Human',\n 'interfaces' =\n [\n $character\n ],\n 'fields' =\n [\n 'height' =\n Type::float(),\n $character-\ngetField('id'),\n $character-\ngetField('name')\n ] \n]);\n\n\n\n\nIn this case field definitions are created only once (as a part of Interface Type) and then \nre-used by all interface implementors. It can save several microseconds and kilobytes + ensures that \nfield definitions of Interface and implementors are always in sync.\n\n\nYet it creates a problem with resolution of such fields. There are two ways how shared fields could \nbe resolved:\n\n\n\n\n\n\nIf field resolution algorithm is the same for all Interface implementors - you can simply add \n\nresolve\n option to field definition in Interface itself.\n\n\n\n\n\n\nIf field resolution varies from implementor to implementor - you can specify \nresolveField\n \noption in \nObject Type config\n and handle field \nresolutions there \n(Note: \nresolve\n option in field definition has precedence over \nresolveField\n option in object type definition)\n\n\n\n\n\n\nInterface role in data fetching\n\n\nThe only responsibility of interface in Data Fetching process is to return concrete Object Type \nfor given \n$value\n in \nresolveType\n. Then resolution of fields is delegated to resolvers of this \nconcrete Object Type.\n\n\nIf \nresolveType\n option is omitted, \ngraphql-php\n will loop through all interface implementors and \nuse their \nisTypeOf\n callback to pick the first suitable one. This is obviously less efficient \nthan single \nresolveType\n call. So it is recommended to define \nresolveType\n whenever possible.", "title": "Interfaces" }, { "location": "/type-system/interfaces/#interface-type-definition", - "text": "An Interface is an abstract type that includes a certain set of fields that a \ntype must include to implement the interface. In graphql-php interface type is an instance of GraphQL\\Type\\Definition\\InterfaceType \n(or one of it subclasses) which accepts configuration array in constructor: use GraphQL\\Type\\Definition\\InterfaceType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$character = new InterfaceType([\n 'name' = 'Character',\n 'description' = 'A character in the Star Wars Trilogy',\n 'fields' = [\n 'id' = [\n 'type' = Type::nonNull(Type::string()),\n 'description' = 'The id of the character.',\n ],\n 'name' = [\n 'type' = Type::string(),\n 'description' = 'The name of the character.'\n ]\n ],\n 'resolveType' = function ($value) {\n if ($value- type === 'human') {\n return MyTypes::human(); \n } else {\n return MyTypes::droid();\n }\n }\n]); This example uses inline style for Interface definition, but there are also other styles (using inheritance or composition).", + "text": "An Interface is an abstract type that includes a certain set of fields that a \ntype must include to implement the interface. In graphql-php interface type is an instance of GraphQL\\Type\\Definition\\InterfaceType \n(or one of it subclasses) which accepts configuration array in constructor: use GraphQL\\Type\\Definition\\InterfaceType;\nuse GraphQL\\Type\\Definition\\Type;\n\n$character = new InterfaceType([\n 'name' = 'Character',\n 'description' = 'A character in the Star Wars Trilogy',\n 'fields' = [\n 'id' = [\n 'type' = Type::nonNull(Type::string()),\n 'description' = 'The id of the character.',\n ],\n 'name' = [\n 'type' = Type::string(),\n 'description' = 'The name of the character.'\n ]\n ],\n 'resolveType' = function ($value) {\n if ($value- type === 'human') {\n return MyTypes::human(); \n } else {\n return MyTypes::droid();\n }\n }\n]); This example uses inline style for Interface definition, but you can also use inheritance .", "title": "Interface Type Definition" }, { @@ -207,12 +217,12 @@ }, { "location": "/type-system/unions/", - "text": "Union Type Definition\n\n\nA Union is an abstract type that simply enumerates other Object Types. \nValue of Union Type is actually a value of one of included Object Types.\n\n\nIn \ngraphql-php\n union type is an instance of \nGraphQL\\Type\\Definition\\UnionType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\n$searchResultType = new UnionType([\n 'name' =\n 'SearchResult',\n 'types' =\n [\n MyTypes::story(),\n MyTypes::user()\n ];\n 'resolveType' =\n function($value) {\n if ($value-\ntype === 'story') {\n return MyTypes::story(); \n } else {\n return MyTypes::user();\n }\n }\n]);\n\n\n\n\nThis example uses \ninline\n style for Union definition, but there are also \n\nother styles\n (using inheritance or composition).\n\n\nConfiguration options\n\n\nConstructor of UnionType accepts an array. Below is a full list of allowed options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Unique name of this interface type within Schema\n\n\n\n\n\n\ntypes\n\n\narray\n\n\nRequired.\n List of Object Types included in this Union. Note that you can't create a Union type out of Interfaces or other Unions.\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\nresolveType\n\n\ncallback\n returning instance of \nObjectType\n\n\nfunction($value, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Any \ncallable\n that receives \n$value\n from resolver of the parent field and returns Object Type for that \n$value\n.", + "text": "Union Type Definition\n\n\nA Union is an abstract type that simply enumerates other Object Types. \nValue of Union Type is actually a value of one of included Object Types.\n\n\nIn \ngraphql-php\n union type is an instance of \nGraphQL\\Type\\Definition\\UnionType\n \n(or one of it subclasses) which accepts configuration array in constructor:\n\n\n$searchResultType = new UnionType([\n 'name' =\n 'SearchResult',\n 'types' =\n [\n MyTypes::story(),\n MyTypes::user()\n ];\n 'resolveType' =\n function($value) {\n if ($value-\ntype === 'story') {\n return MyTypes::story(); \n } else {\n return MyTypes::user();\n }\n }\n]);\n\n\n\n\nThis example uses \ninline\n style for Union definition, but you can also use\n\n\ninheritance\n.\n\n\nConfiguration options\n\n\nConstructor of UnionType accepts an array. Below is a full list of allowed options:\n\n\n\n\n\n\n\n\nOption\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nname\n\n\nstring\n\n\nRequired.\n Unique name of this interface type within Schema\n\n\n\n\n\n\ntypes\n\n\narray\n\n\nRequired.\n List of Object Types included in this Union. Note that you can't create a Union type out of Interfaces or other Unions.\n\n\n\n\n\n\ndescription\n\n\nstring\n\n\nPlain-text description of this type for clients (e.g. used by \nGraphiQL\n for auto-generated documentation)\n\n\n\n\n\n\nresolveType\n\n\ncallback\n returning instance of \nObjectType\n\n\nfunction($value, $context, GraphQL\\Type\\Definition\\ResolveInfo $info)\n Any \ncallable\n that receives \n$value\n from resolver of the parent field and returns Object Type for that \n$value\n.", "title": "Unions" }, { "location": "/type-system/unions/#union-type-definition", - "text": "A Union is an abstract type that simply enumerates other Object Types. \nValue of Union Type is actually a value of one of included Object Types. In graphql-php union type is an instance of GraphQL\\Type\\Definition\\UnionType \n(or one of it subclasses) which accepts configuration array in constructor: $searchResultType = new UnionType([\n 'name' = 'SearchResult',\n 'types' = [\n MyTypes::story(),\n MyTypes::user()\n ];\n 'resolveType' = function($value) {\n if ($value- type === 'story') {\n return MyTypes::story(); \n } else {\n return MyTypes::user();\n }\n }\n]); This example uses inline style for Union definition, but there are also other styles (using inheritance or composition).", + "text": "A Union is an abstract type that simply enumerates other Object Types. \nValue of Union Type is actually a value of one of included Object Types. In graphql-php union type is an instance of GraphQL\\Type\\Definition\\UnionType \n(or one of it subclasses) which accepts configuration array in constructor: $searchResultType = new UnionType([\n 'name' = 'SearchResult',\n 'types' = [\n MyTypes::story(),\n MyTypes::user()\n ];\n 'resolveType' = function($value) {\n if ($value- type === 'story') {\n return MyTypes::story(); \n } else {\n return MyTypes::user();\n }\n }\n]); This example uses inline style for Union definition, but you can also use inheritance .", "title": "Union Type Definition" }, { @@ -282,12 +292,12 @@ }, { "location": "/executing-queries/", - "text": "Overview\n\n\nQuery execution is a complex process involving multiple steps, including query \nparsing\n, \n\nvalidating\n and finally \nexecuting\n against your \nschema\n.\n\n\ngraphql-php\n provides convenient facade for this process in class \nGraphQL\\GraphQL\n:\n\n\nuse GraphQL\\GraphQL;\n\n$result = GraphQL::execute(\n $schema, \n $queryString, \n $rootValue = null, \n $contextValue = null, \n $variableValues = null, \n $operationName = null\n);\n\n\n\n\nMethod returns \narray\n with \ndata\n and \nerrors\n keys, as described by \n\nGraphQL specs\n.\nThis array is suitable for further serialization (e.g. using \njson_encode\n). \nSee also section on \nerror handling\n.\n\n\nDescription of method arguments:\n\n\n\n\n\n\n\n\nArgument\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nschema\n\n\nGraphQL\\Schema\n\n\nRequired.\n Instance of your application \nSchema\n\n\n\n\n\n\nqueryString\n\n\nstring\n or \nGraphQL\\Language\\AST\\Document\n\n\nRequired.\n Actual GraphQL query string to be parsed, validated and executed. If you parse query elsewhere before executing - pass corresponding ast document here to avoid new parsing.\n\n\n\n\n\n\nrootValue\n\n\nmixed\n\n\nAny value that represents a root of your data graph. It is passed as 1st argument to field resolvers of \nQuery type\n. Can be omitted or set to null if actual root values are fetched by Query type itself.\n\n\n\n\n\n\ncontextValue\n\n\nmixed\n\n\nAny value that holds information shared between all field resolvers. Most often they use it to pass currently logged in user, locale details, etc.\nIt will be available as 3rd argument in all field resolvers. (see section on \nField Definitions\n for reference) \ngraphql-php\n never modifies this value and passes it \nas is\n to all underlying resolvers.\n\n\n\n\n\n\nvariableValues\n\n\narray\n\n\nMap of variable values passed along with query string. See section on \nquery variables on official GraphQL website\n\n\n\n\n\n\noperationName\n\n\nstring\n\n\nAllows the caller to specify which operation in queryString will be run, in cases where queryString contains multiple top-level operations.\n\n\n\n\n\n\n\n\nParsing\n\n\nFollowing reading describes implementation details of query execution process. It may clarify some \ninternals of GraphQL but is not required in order to use it. Feel free to skip to next section \non \nError Handling\n for essentials.\n\n\nTODOC\n\n\nValidating\n\n\nTODOC\n\n\nExecuting\n\n\nTODOC", + "text": "Overview\n\n\nQuery execution is a complex process involving multiple steps, including query \nparsing\n, \n\nvalidating\n and finally \nexecuting\n against your \nschema\n.\n\n\ngraphql-php\n provides convenient facade for this process in class \nGraphQL\\GraphQL\n:\n\n\nuse GraphQL\\GraphQL;\n\n$result = GraphQL::execute(\n $schema, \n $queryString, \n $rootValue = null, \n $contextValue = null, \n $variableValues = null, \n $operationName = null\n);\n\n\n\n\nMethod returns \narray\n with \ndata\n and \nerrors\n keys, as described by \n\nGraphQL specs\n.\nThis array is suitable for further serialization (e.g. using \njson_encode\n). \nSee also section on \nerror handling\n.\n\n\nDescription of method arguments:\n\n\n\n\n\n\n\n\nArgument\n\n\nType\n\n\nNotes\n\n\n\n\n\n\n\n\n\n\nschema\n\n\nGraphQL\\Schema\n\n\nRequired.\n Instance of your application \nSchema\n\n\n\n\n\n\nqueryString\n\n\nstring\n or \nGraphQL\\Language\\AST\\DocumentNode\n\n\nRequired.\n Actual GraphQL query string to be parsed, validated and executed. If you parse query elsewhere before executing - pass corresponding ast document here to avoid new parsing.\n\n\n\n\n\n\nrootValue\n\n\nmixed\n\n\nAny value that represents a root of your data graph. It is passed as 1st argument to field resolvers of \nQuery type\n. Can be omitted or set to null if actual root values are fetched by Query type itself.\n\n\n\n\n\n\ncontextValue\n\n\nmixed\n\n\nAny value that holds information shared between all field resolvers. Most often they use it to pass currently logged in user, locale details, etc.\nIt will be available as 3rd argument in all field resolvers. (see section on \nField Definitions\n for reference) \ngraphql-php\n never modifies this value and passes it \nas is\n to all underlying resolvers.\n\n\n\n\n\n\nvariableValues\n\n\narray\n\n\nMap of variable values passed along with query string. See section on \nquery variables on official GraphQL website\n\n\n\n\n\n\noperationName\n\n\nstring\n\n\nAllows the caller to specify which operation in queryString will be run, in cases where queryString contains multiple top-level operations.\n\n\n\n\n\n\n\n\nParsing\n\n\nFollowing reading describes implementation details of query execution process. It may clarify some \ninternals of GraphQL but is not required in order to use it. Feel free to skip to next section \non \nError Handling\n for essentials.\n\n\nTODOC\n\n\nValidating\n\n\nTODOC\n\n\nExecuting\n\n\nTODOC", "title": "Executing Queries" }, { "location": "/executing-queries/#overview", - "text": "Query execution is a complex process involving multiple steps, including query parsing , validating and finally executing against your schema . graphql-php provides convenient facade for this process in class GraphQL\\GraphQL : use GraphQL\\GraphQL;\n\n$result = GraphQL::execute(\n $schema, \n $queryString, \n $rootValue = null, \n $contextValue = null, \n $variableValues = null, \n $operationName = null\n); Method returns array with data and errors keys, as described by GraphQL specs .\nThis array is suitable for further serialization (e.g. using json_encode ). \nSee also section on error handling . Description of method arguments: Argument Type Notes schema GraphQL\\Schema Required. Instance of your application Schema queryString string or GraphQL\\Language\\AST\\Document Required. Actual GraphQL query string to be parsed, validated and executed. If you parse query elsewhere before executing - pass corresponding ast document here to avoid new parsing. rootValue mixed Any value that represents a root of your data graph. It is passed as 1st argument to field resolvers of Query type . Can be omitted or set to null if actual root values are fetched by Query type itself. contextValue mixed Any value that holds information shared between all field resolvers. Most often they use it to pass currently logged in user, locale details, etc. It will be available as 3rd argument in all field resolvers. (see section on Field Definitions for reference) graphql-php never modifies this value and passes it as is to all underlying resolvers. variableValues array Map of variable values passed along with query string. See section on query variables on official GraphQL website operationName string Allows the caller to specify which operation in queryString will be run, in cases where queryString contains multiple top-level operations.", + "text": "Query execution is a complex process involving multiple steps, including query parsing , validating and finally executing against your schema . graphql-php provides convenient facade for this process in class GraphQL\\GraphQL : use GraphQL\\GraphQL;\n\n$result = GraphQL::execute(\n $schema, \n $queryString, \n $rootValue = null, \n $contextValue = null, \n $variableValues = null, \n $operationName = null\n); Method returns array with data and errors keys, as described by GraphQL specs .\nThis array is suitable for further serialization (e.g. using json_encode ). \nSee also section on error handling . Description of method arguments: Argument Type Notes schema GraphQL\\Schema Required. Instance of your application Schema queryString string or GraphQL\\Language\\AST\\DocumentNode Required. Actual GraphQL query string to be parsed, validated and executed. If you parse query elsewhere before executing - pass corresponding ast document here to avoid new parsing. rootValue mixed Any value that represents a root of your data graph. It is passed as 1st argument to field resolvers of Query type . Can be omitted or set to null if actual root values are fetched by Query type itself. contextValue mixed Any value that holds information shared between all field resolvers. Most often they use it to pass currently logged in user, locale details, etc. It will be available as 3rd argument in all field resolvers. (see section on Field Definitions for reference) graphql-php never modifies this value and passes it as is to all underlying resolvers. variableValues array Map of variable values passed along with query string. See section on query variables on official GraphQL website operationName string Allows the caller to specify which operation in queryString will be run, in cases where queryString contains multiple top-level operations.", "title": "Overview" }, { @@ -307,7 +317,7 @@ }, { "location": "/error-handling/", - "text": "Errors in GraphQL\n\n\nQuery execution process never throws exceptions. Instead all errors that occur during query execution\nare caught, collected and included in response. \n\n\nThere are 3 types of errors in GraphQL (Syntax, Validation and Execution errors):\n\n\nSyntax\n errors are returned in response when query has invalid syntax and could not be parsed.\nExample output for invalid query \n{hello\n (missing bracket):\n\n\n[\n 'errors' =\n [\n [\n 'message' =\n \nSyntax Error GraphQL request (1:7) Expected Name, found \nEOF\n\\n\\n1: {hello\\n ^\\n\n,\n 'locations' =\n [\n ['line' =\n 1, 'column' =\n 7]\n ]\n ]\n ]\n]\n\n\n\n\nValidation\n errors - returned in response when query has semantic errors. \nExample output for invalid query \n{unknownField}\n:\n\n\n[\n 'errors' =\n [\n [\n 'message' =\n 'Cannot query field \nunknownField\n on type \nQuery\n.',\n 'locations' =\n [\n ['line' =\n 1, 'column' =\n 2]\n ]\n ]\n ]\n]\n\n\n\n\nExecution\n errors - included in response when some field resolver throws \n(or returns unexpected value). Example output for query with exception thrown in \nfield resolver \n{fieldWithException}\n:\n\n\n[\n 'data' =\n [\n 'fieldWithException' =\n null\n ],\n 'errors' =\n [\n [\n 'message' =\n 'Exception message thrown in field resolver',\n 'locations' =\n [\n ['line' =\n 1, 'column' =\n 2]\n ],\n 'path': [\n 'fieldWithException'\n ]\n ]\n ]\n]\n\n\n\n\nObviously when \nSyntax\n or \nValidation\n error is detected - process is interrupted and query is not \nexecuted. In such scenarios response only contains \nerrors\n, but not \ndata\n.\n\n\nGraphQL is forgiving to \nExecution\n errors which occur in resolvers of nullable fields. \nIf such field throws or returns unexpected value the value of the field in response will be simply \nreplaced with \nnull\n and error entry will be added to response.\n\n\nIf exception is thrown in non-null field - it will be bubbled up to first nullable field which will\nbe replaced with \nnull\n (and error entry added to response). If all fields up to the root are non-null - \n\ndata\n entry will be removed from n response and only \nerrors\n key will be presented.\n\n\nDebugging tools\n\n\nEach error entry contains pointer to line and column in original query string which caused \nthe error:\n\n\n'locations' =\n [\n ['line' =\n 1, 'column' =\n 2]\n]\n\n\n\n\nGraphQL clients like \nRelay\n or \nGraphiQL\n leverage this information to highlight \nactual piece of query containing error. \n\n\nIn some cases (like deep fragment fields) locations will include several entries to track down the \npath to field with error in query.\n\n\nExecution\n errors also contain \npath\n from the very root field to actual field value producing \nan error (including indexes for array types and fieldNames for object types). So in complex situation \nthis path could look like this:\n\n\n'path' =\n [\n 'lastStoryPosted',\n 'author',\n 'friends',\n 3\n 'fieldWithException'\n]\n\n\n\n\nCustom Error Formatting\n\n\nIf you want to apply custom formatting to errors - use \nGraphQL::executeAndReturnResult()\n instead\nof \nGraphQL::execute()\n.\n\n\nIt has exactly the same \nsignature\n, but instead of array it \nreturns \nGraphQL\\Executor\\ExecutionResult\n instance which holds errors in public \n$errors\n \nproperty and data in \n$data\n property.\n\n\nEach entry of \n$errors\n array contains instance of \nGraphQL\\Error\\Error\n which wraps original \nexceptions thrown by resolvers. To access original exceptions use \n$error-\ngetPrevious()\n method.\nBut note that previous exception is only available for \nExecution\n errors and will be \nnull\n\nfor \nSyntax\n or \nValidation\n errors.\n\n\nSchema Errors\n\n\nSo far we only covered errors which occur during query execution process. But schema definition can \nalso throw if there is an error in one of type definitions.\n\n\nUsually such errors mean that there is some logical error in your schema and it is the only case \nwhen it makes sense to return \n500\n error code for GraphQL endpoint:\n\n\ntry {\n $schema = new Schema([\n // ...\n ]);\n\n $result = GraphQL::execute($schema, $query);\n} catch(\\Exception $e) {\n header('Content-Type: application/json', true, 500);\n echo json_encode([\n 'message' =\n 'Unexpected error'\n ]);\n exit;\n}", + "text": "Errors in GraphQL\n\n\nQuery execution process never throws exceptions. Instead all errors that occur during query execution\nare caught, collected and included in response. \n\n\nThere are 3 types of errors in GraphQL (Syntax, Validation and Execution errors):\n\n\nSyntax\n errors are returned in response when query has invalid syntax and could not be parsed.\nExample output for invalid query \n{hello\n (missing bracket):\n\n\n[\n 'errors' =\n [\n [\n 'message' =\n \nSyntax Error GraphQL request (1:7) Expected Name, found \nEOF\n\\n\\n1: {hello\\n ^\\n\n,\n 'locations' =\n [\n ['line' =\n 1, 'column' =\n 7]\n ]\n ]\n ]\n]\n\n\n\n\nValidation\n errors - returned in response when query has semantic errors. \nExample output for invalid query \n{unknownField}\n:\n\n\n[\n 'errors' =\n [\n [\n 'message' =\n 'Cannot query field \nunknownField\n on type \nQuery\n.',\n 'locations' =\n [\n ['line' =\n 1, 'column' =\n 2]\n ]\n ]\n ]\n]\n\n\n\n\nExecution\n errors - included in response when some field resolver throws \n(or returns unexpected value). Example output for query with exception thrown in \nfield resolver \n{fieldWithException}\n:\n\n\n[\n 'data' =\n [\n 'fieldWithException' =\n null\n ],\n 'errors' =\n [\n [\n 'message' =\n 'Exception message thrown in field resolver',\n 'locations' =\n [\n ['line' =\n 1, 'column' =\n 2]\n ],\n 'path': [\n 'fieldWithException'\n ]\n ]\n ]\n]\n\n\n\n\nObviously when \nSyntax\n or \nValidation\n error is detected - process is interrupted and query is not \nexecuted. In such scenarios response only contains \nerrors\n, but not \ndata\n.\n\n\nGraphQL is forgiving to \nExecution\n errors which occur in resolvers of nullable fields. \nIf such field throws or returns unexpected value the value of the field in response will be simply \nreplaced with \nnull\n and error entry will be added to response.\n\n\nIf exception is thrown in non-null field - it will be bubbled up to first nullable field which will\nbe replaced with \nnull\n (and error entry added to response). If all fields up to the root are non-null - \n\ndata\n entry will be removed from n response and only \nerrors\n key will be presented.\n\n\nDebugging tools\n\n\nEach error entry contains pointer to line and column in original query string which caused \nthe error:\n\n\n'locations' =\n [\n ['line' =\n 1, 'column' =\n 2]\n]\n\n\n\n\nGraphQL clients like \nRelay\n or \nGraphiQL\n leverage this information to highlight \nactual piece of query containing error. \n\n\nIn some cases (like deep fragment fields) locations will include several entries to track down the \npath to field with error in query.\n\n\nExecution\n errors also contain \npath\n from the very root field to actual field value producing \nan error (including indexes for array types and fieldNames for object types). So in complex situation \nthis path could look like this:\n\n\n'path' =\n [\n 'lastStoryPosted',\n 'author',\n 'friends',\n 3\n 'fieldWithException'\n]\n\n\n\n\nCustom Error Formatting\n\n\nIf you want to apply custom formatting to errors - use \nGraphQL::executeAndReturnResult()\n instead\nof \nGraphQL::execute()\n.\n\n\nIt has exactly the same \nsignature\n, but instead of array it \nreturns \nGraphQL\\Executor\\ExecutionResult\n instance which holds errors in public \n$errors\n \nproperty and data in \n$data\n property.\n\n\nEach entry of \n$errors\n array contains instance of \nGraphQL\\Error\\Error\n which wraps original \nexceptions thrown by resolvers. To access original exceptions use \n$error-\ngetPrevious()\n method.\nBut note that previous exception is only available for \nExecution\n errors and will be \nnull\n\nfor \nSyntax\n or \nValidation\n errors.\n\n\nSchema Errors\n\n\nSo far we only covered errors which occur during query execution process. But schema definition can \nalso throw if there is an error in one of type definitions.\n\n\nUsually such errors mean that there is some logical error in your schema and it is the only case \nwhen it makes sense to return \n500\n error code for GraphQL endpoint:\n\n\ntry {\n $schema = new Schema([\n // ...\n ]);\n\n $body = GraphQL::execute($schema, $query);\n $status = 200;\n} catch(\\Exception $e) {\n $body = json_encode([\n 'message' =\n 'Unexpected error'\n ]);\n $status = 500;\n}\n\nheader('Content-Type: application/json', true, $status);\necho json_encode($body);", "title": "Handling Errors" }, { @@ -327,43 +337,23 @@ }, { "location": "/error-handling/#schema-errors", - "text": "So far we only covered errors which occur during query execution process. But schema definition can \nalso throw if there is an error in one of type definitions. Usually such errors mean that there is some logical error in your schema and it is the only case \nwhen it makes sense to return 500 error code for GraphQL endpoint: try {\n $schema = new Schema([\n // ...\n ]);\n\n $result = GraphQL::execute($schema, $query);\n} catch(\\Exception $e) {\n header('Content-Type: application/json', true, 500);\n echo json_encode([\n 'message' = 'Unexpected error'\n ]);\n exit;\n}", + "text": "So far we only covered errors which occur during query execution process. But schema definition can \nalso throw if there is an error in one of type definitions. Usually such errors mean that there is some logical error in your schema and it is the only case \nwhen it makes sense to return 500 error code for GraphQL endpoint: try {\n $schema = new Schema([\n // ...\n ]);\n\n $body = GraphQL::execute($schema, $query);\n $status = 200;\n} catch(\\Exception $e) {\n $body = json_encode([\n 'message' = 'Unexpected error'\n ]);\n $status = 500;\n}\n\nheader('Content-Type: application/json', true, $status);\necho json_encode($body);", "title": "Schema Errors" }, - { - "location": "/data-fetching/", - "text": "", - "title": "Fetching Data" - }, - { - "location": "/best-practices/", - "text": "Config Validation\n\n\nDefining types using arrays may be error-prone, but \ngraphql-php\n provides config validation\ntool to report when config has unexpected structure. \n\n\nThis validation tool is \ndisabled by default\n because it is time-consuming operation which only \nmakes sense during development.\n\n\nTo enable validation - call: \nGraphQL\\Type\\Definition\\Config::enableValidation();\n in your bootstrap\nbut make sure to restrict it to debug/development mode only.\n\n\nType Registry\n\n\ngraphql-php\n expects that each type in Schema is presented with single instance. Therefore\nif you define your types as separate PHP classes you need to ensure that each type is referenced only once.\n\n\nTechnically you can create several instances of your type (for example for tests), but \nGraphQL\\Schema\n \nwill throw on attempt to add different instances with the same name.\n\n\nThere are several ways to achieve this depending on your preferences. We provide reference \nimplementation below that introduces TypeRegistry class:", - "title": "Best Practices" - }, - { - "location": "/best-practices/#config-validation", - "text": "Defining types using arrays may be error-prone, but graphql-php provides config validation\ntool to report when config has unexpected structure. This validation tool is disabled by default because it is time-consuming operation which only \nmakes sense during development. To enable validation - call: GraphQL\\Type\\Definition\\Config::enableValidation(); in your bootstrap\nbut make sure to restrict it to debug/development mode only.", - "title": "Config Validation" - }, - { - "location": "/best-practices/#type-registry", - "text": "graphql-php expects that each type in Schema is presented with single instance. Therefore\nif you define your types as separate PHP classes you need to ensure that each type is referenced only once. Technically you can create several instances of your type (for example for tests), but GraphQL\\Schema \nwill throw on attempt to add different instances with the same name. There are several ways to achieve this depending on your preferences. We provide reference \nimplementation below that introduces TypeRegistry class:", - "title": "Type Registry" - }, { "location": "/complementary-tools/", - "text": "Relay\n\n\nGraphiQL", + "text": "Integrations\n\n\n\n\nIntegration with Relay\n\n\nIntegration with Laravel 5\n + \nRelay Helpers for Laravel\n\n\nSymfony Bundle\n by Overblog\n\n\n\n\nTools\n\n\n\n\nGraphiQL\n - An in-browser IDE for exploring GraphQL\n\n\nChromeiQL\n\n or \nGraphiQL Feen\n -\n GraphiQL as Google Chrome extension", "title": "Complementary Tools" }, { - "location": "/complementary-tools/#relay", - "text": "", - "title": "Relay" + "location": "/complementary-tools/#integrations", + "text": "Integration with Relay Integration with Laravel 5 + Relay Helpers for Laravel Symfony Bundle by Overblog", + "title": "Integrations" }, { - "location": "/complementary-tools/#graphiql", - "text": "", - "title": "GraphiQL" + "location": "/complementary-tools/#tools", + "text": "GraphiQL - An in-browser IDE for exploring GraphQL ChromeiQL \n or GraphiQL Feen -\n GraphiQL as Google Chrome extension", + "title": "Tools" } ] } \ No newline at end of file diff --git a/search.html b/search.html index 617cfeb..7ae79ef 100755 --- a/search.html +++ b/search.html @@ -153,20 +153,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • diff --git a/sitemap.xml b/sitemap.xml index 0666f6a..6a7ca01 100755 --- a/sitemap.xml +++ b/sitemap.xml @@ -4,7 +4,7 @@ None/ - 2016-11-08 + 2016-11-25 daily @@ -12,7 +12,7 @@ None/getting-started/ - 2016-11-08 + 2016-11-25 daily @@ -21,61 +21,61 @@ None/type-system/ - 2016-11-08 + 2016-11-25 daily None/type-system/object-types/ - 2016-11-08 + 2016-11-25 daily None/type-system/scalar-types/ - 2016-11-08 + 2016-11-25 daily None/type-system/enum-types/ - 2016-11-08 + 2016-11-25 daily None/type-system/lists-and-nonnulls/ - 2016-11-08 + 2016-11-25 daily None/type-system/interfaces/ - 2016-11-08 + 2016-11-25 daily None/type-system/unions/ - 2016-11-08 + 2016-11-25 daily None/type-system/input-types/ - 2016-11-08 + 2016-11-25 daily None/type-system/directives/ - 2016-11-08 + 2016-11-25 daily None/type-system/schema/ - 2016-11-08 + 2016-11-25 daily @@ -84,7 +84,7 @@ None/executing-queries/ - 2016-11-08 + 2016-11-25 daily @@ -92,23 +92,7 @@ None/error-handling/ - 2016-11-08 - daily - - - - - - None/data-fetching/ - 2016-11-08 - daily - - - - - - None/best-practices/ - 2016-11-08 + 2016-11-25 daily @@ -116,7 +100,7 @@ None/complementary-tools/ - 2016-11-08 + 2016-11-25 daily diff --git a/type-system/directives/index.html b/type-system/directives/index.html index 9cbd154..c1e6fa5 100755 --- a/type-system/directives/index.html +++ b/type-system/directives/index.html @@ -167,20 +167,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • diff --git a/type-system/enum-types/index.html b/type-system/enum-types/index.html index 52614bb..cb0970b 100755 --- a/type-system/enum-types/index.html +++ b/type-system/enum-types/index.html @@ -173,20 +173,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -260,8 +246,8 @@ $episodeEnum = new EnumType([ ]); -

    This example uses inline style for Enum Type definition, but there are also -other styles (using inheritance or composition).

    +

    This example uses inline style for Enum Type definition, but you can also use +inheritance.

    Configuration options

    Enum Type constructor accepts array with following options:

    diff --git a/type-system/index.html b/type-system/index.html index 7d777ae..12595ab 100755 --- a/type-system/index.html +++ b/type-system/index.html @@ -170,20 +170,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -253,7 +239,7 @@ $myType = new ObjectType([ ]); -

    Class per type, using inheritance:

    +

    Class per type:

    <?php
     namespace MyApp;
     
    @@ -276,30 +262,6 @@ class MyType extends ObjectType
     }
     
    -

    Class per type, using composition:

    -
    <?php
    -namespace MyApp;
    -
    -use GraphQL\Type\Definition\ObjectType;
    -use GraphQL\Type\Definition\Type;
    -use GraphQL\Type\DefinitionContainer;
    -
    -class MyType implements DefinitionContainer
    -{
    -    private $definition;
    -
    -    public function getDefinition()
    -    {
    -        return $this->definition ?: ($this->definition = new ObjectType([
    -            'name' => 'MyType',
    -            'fields' => [
    -                'id' => Type::id()
    -            ]
    -        ]));
    -    }
    -}
    -
    -

    You can also mix-and-match styles for convenience. For example:

    <?php
     namespace MyApp;
    @@ -328,7 +290,7 @@ class BlogPostType extends ObjectType
     

    Type Registry

    -

    Every type must be presented in Schema with single instance (graphql-php +

    Every type must be presented in Schema by single instance (graphql-php throws when it discovers several instances with the same name in schema).

    Therefore if you define your type as separate PHP class you must ensure that only one instance of that class is added to schema.

    diff --git a/type-system/input-types/index.html b/type-system/input-types/index.html index b9475b2..3fb8c79 100755 --- a/type-system/input-types/index.html +++ b/type-system/input-types/index.html @@ -173,20 +173,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • diff --git a/type-system/interfaces/index.html b/type-system/interfaces/index.html index 9adc43f..e4a684a 100755 --- a/type-system/interfaces/index.html +++ b/type-system/interfaces/index.html @@ -179,20 +179,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -270,8 +256,8 @@ $character = new InterfaceType([ ]); -

    This example uses inline style for Interface definition, but there are also -other styles (using inheritance or composition).

    +

    This example uses inline style for Interface definition, but you can also use
    +inheritance.

    Configuration options

    Constructor of InterfaceType accepts an array. Below is a full list of allowed options:

  • diff --git a/type-system/lists-and-nonnulls/index.html b/type-system/lists-and-nonnulls/index.html index 0a073e6..1024646 100755 --- a/type-system/lists-and-nonnulls/index.html +++ b/type-system/lists-and-nonnulls/index.html @@ -167,20 +167,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • diff --git a/type-system/object-types/index.html b/type-system/object-types/index.html index 90f1b39..687d572 100755 --- a/type-system/object-types/index.html +++ b/type-system/object-types/index.html @@ -185,20 +185,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -300,8 +286,8 @@ $blogStory = new ObjectType([ ]); -

    This example uses inline style for Object Type definitions, but there are also -other styles (using inheritance or composition).

    +

    This example uses inline style for Object Type definitions, but you can also use
    +inheritance.

    Configuration options

    Object type constructor expects configuration array. Below is a full list of available options:

  • diff --git a/type-system/scalar-types/index.html b/type-system/scalar-types/index.html index 3dae067..a87e5a8 100755 --- a/type-system/scalar-types/index.html +++ b/type-system/scalar-types/index.html @@ -167,20 +167,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -264,12 +250,12 @@ or hardcoded in source code) to serialized representation inclu

    Those cases are covered by methods serialize, parseValue and parseLiteral of abstract ScalarType class respectively.

    -

    Here is an example of simple Email type (using inheritance):

    +

    Here is an example of simple Email type:

    <?php
     namespace MyApp;
     
     use GraphQL\Error\Error;
    -use GraphQL\Language\AST\StringValue;
    +use GraphQL\Language\AST\StringValueNode;
     use GraphQL\Type\Definition\ScalarType;
     use GraphQL\Utils;
     
    @@ -317,44 +303,21 @@ class EmailType extends ScalarType
          *   user(email: "user@example.com") 
          * }
          *
    -     * @param \GraphQL\Language\AST\Node $valueAST
    +     * @param \GraphQL\Language\AST\Node $valueNode
          * @return string
          * @throws Error
          */
    -    public function parseLiteral($valueAST)
    +    public function parseLiteral($valueNode)
         {
             // Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL
             // error location in query:
    -        if (!$valueAST instanceof StringValue) {
    -            throw new Error('Query error: Can only parse strings got: ' . $valueAST->kind, [$valueAST]);
    +        if (!$valueNode instanceof StringValueNode) {
    +            throw new Error('Query error: Can only parse strings got: ' . $valueNode->kind, [$valueNode]);
             }
    -        if (!filter_var($valueAST->value, FILTER_VALIDATE_EMAIL)) {
    -            throw new Error("Not a valid email", [$valueAST]);
    +        if (!filter_var($valueNode->value, FILTER_VALIDATE_EMAIL)) {
    +            throw new Error("Not a valid email", [$valueNode]);
             }
    -        return $valueAST->value;
    -    }
    -}
    -
    - -

    Same example, using composition over inheritance:

    -
    <?php
    -namespace MyApp;
    -
    -use GraphQL\Type\DefinitionContainer;
    -use GraphQL\Type\Definition\CustomScalarType;
    -
    -class EmailType implements DefinitionContainer
    -{
    -    private $definition;
    -
    -    public function getDefinition()
    -    {
    -        return $this->definition ?: ($this->definition = new CustomScalarType([
    -            'name' => 'Email',
    -            'serialize' => function($value) {/* See function body above */},
    -            'parseValue' => function($value) {/* See function body above */},
    -            'parseLiteral' => function($valueAST) {/* See function body above */},
    -        ]));
    +        return $valueNode->value;
         }
     }
     
    @@ -367,7 +330,7 @@ $emailType = new CustomScalarType([ 'name' => 'Email', 'serialize' => function($value) {/* See function body above */}, 'parseValue' => function($value) {/* See function body above */}, - 'parseLiteral' => function($valueAST) {/* See function body above */}, + 'parseLiteral' => function($valueNode) {/* See function body above */}, ]); diff --git a/type-system/schema/index.html b/type-system/schema/index.html index 620bba8..a0edca9 100755 --- a/type-system/schema/index.html +++ b/type-system/schema/index.html @@ -170,20 +170,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • diff --git a/type-system/unions/index.html b/type-system/unions/index.html index aaf3e54..3ca9a65 100755 --- a/type-system/unions/index.html +++ b/type-system/unions/index.html @@ -167,20 +167,6 @@
  • Handling Errors -
  • -
  • - -
  • -
  • - Fetching Data - -
  • -
  • - -
  • -
  • - Best Practices -
  • @@ -248,8 +234,8 @@ Value of Union Type is actually a value of one of included Object Types.

    ]); -

    This example uses inline style for Union definition, but there are also -other styles (using inheritance or composition).

    +

    This example uses inline style for Union definition, but you can also use
    +inheritance.

    Configuration options

    Constructor of UnionType accepts an array. Below is a full list of allowed options: