Download the PHP package chemisus/graphql without Composer
On this page you can find all versions of the php package chemisus/graphql. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package graphql
composer require chemisus/graphql
GraphQL
If you're looking for a reactive, two phase, BFS, graphql library†, then you've found it!
What do you mean by "two phases"?
The execution of a query consists of two phases: fetch and resolve.
Fetch Phase
The primary goal of the fetch phase is to try retrieve any data necessary to complete the query, efficiently in terms of connections and/or data transfer. Any items that are fetched will be stored on the node, and can then be referenced by child nodes during their fetch process, or the node itself during its resolve process.
The fetch phase is executed in a BFS manner.
The fetch phase utilizes ReactPHP, allowing a node to return promises. If a promise is returned, child nodes will not begin their fetch until the promise has been resolved.
HTTP
A very basic HTTP helper is included that provides non-blocking, allowing nodes to process while other nodes fetch data. Each method returns a promise.
SQL
Unfortunately, PDO (and by extension any library that relies on it) does not support non-blocking queries. It appears possible to get the old-school mysqli library to work with non-blocking queries. Issue #10 was made to look into it.
Resolve Phase
Once the fetch phase is complete, the resolve phase will then assemble the result by allowing each node to generate, or select its value(s) for the final result.
The resolve phase is executed in a DFS manner.
While resolving does not currently support promises or callbacks being returned, issue #5 is tracking the progress.
Nodes
A Node
will contain combined information that is useful when wiring a document.
Node::getDocument()
gets the document itselfNode::arg(string $key, $default=null)
gets an argument if it was specified, $default otherwise.Node::args()
gets all arguments that were specified.Node::getSelection()
gets all fields specifiedNode::getParent()
gets the parent nodeNode::getItems()
gets items that were fetched for the node
Document Wiring
So now we know why the need for fetch and resolve phases, but we still need to specify what they actually do for an application. This is where wirings come in.
A document has four wire operations, each of which can be placed into one of the two following categories: nodes and edges.
Fetcher
Document::fetch(Fetcher $fetcher)
adds a fetcher to the document. A fetcher is
an edge operation, and as previously discussed, will allow fetching data in bulk.
The value returned by a fetcher should be an array, even if the node type itself
is not a list. The items returned by the fetcher will be available in that node's
Node::getItems()
. During execution, for each time an edge is specified in
a query, the edge's fetcher will be called once. Each time the fetcher is
called, the node provided could have different items, arguments, or children.
Resolver
Document::resolve(Resolver $resolver)
adds a resolver to the document. A
resolver is an edge operation, and as previously discussed, will determine the
final result for an edge.
Coercer
Document::coerce(Coercer $coercer)
adds a coercer to the document. A coercer is
a node operation that will translate a node's value into a json value. The value
returned by Coercer::coerce(Node $node, $value)
should be a mixed value that
follows the schema's definition for that node.
If the node is an object, then it helps to think of the coercer as a great way to specify multiple resolvers. The value returned by the coercer should be an object containing at a minimum the fields that do not have resolvers defined for them. The values for the object themselves do not need to be coerced, as they will be coerced later if they were specified in the query.
Typer
Document::type(Typer $typer)
adds a typer to the document. A typer is a node
operation that will determine the concrete type of a value, if the node's type
is an interface or union. The value returned by Typer::type(Node $node, $value)
should be an instance of a Type, which can be obtained by
$node->getDocument()->getType($name)
;
Wiring Example
Node: BookWirer
Node: PersonWirer
Edge: QueryBookWirer
Edge: QueryBooksWirer
Edge: BookAuthorWirer
Document Execution
Extensions
These extensions are provided by default, however, might be moved to their own plugin package at a later date.
Requirements
- php 7.1
Development & Testing
This package can setup a docker container using docker-compose for its testing environment.
Docker Environment
ant
will do everything needed to run tests, including setting up
the docker container.
Host Environment
ant -Dcontained=true
will do the same, but on the host instead.
Testing
There are two main test runners: SchemaTest
and ErrorsTest
.
SchemaTest
SchemaTest
will load a schema, run queries against it, then compare
the actual result to expected results.
To add a schema, create a file at
./resources/test/schema/<schemaName>.gql
.
To add a query for a schema, create the files
./resources/test/schema/<schemaName>/<queryName>.gql
for the query, and
./resources/test/schema/<schemaName>/<queryName>.json
for the results.
To add a wirer for a schema, create a Wirer class at
./src/test/Wirers/<schemaName>DocumentWirer.php
SchemaTest
will detect the files once created, and load them automatically.
ErrorsTest
ErrorsTest
is to test the various errors that graphql specifies.
All versions of graphql with dependencies
webonyx/graphql-php Version ^0.11.2
react/http-client Version ^0.5.6
react/event-loop Version ^0.4.3