Download the PHP package studio-net/laravel-graphql without Composer
On this page you can find all versions of the php package studio-net/laravel-graphql. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download studio-net/laravel-graphql
More information about studio-net/laravel-graphql
Files in studio-net/laravel-graphql
Package laravel-graphql
Short Description GraphQL implementation with power of Laravel
License MIT
Informations about the package laravel-graphql
Laravel GraphQL
Use Facebook GraphQL with Laravel 5.2 >=. It is based on the PHP implementation here. You can find more information about GraphQL in the GraphQL Introduction on the React blog or you can read the GraphQL specifications.
Installation
If you're not using Laravel 5.5>=, don't forget to append facade and service
provider to you config/app.php
file. Next, you have to publish vendor.
Usage
- Definition
- Query
- Mutation
- Pipeline
- Require authorization
- Self documentation
- Examples
- N+1 Problem
Definition
Each source of data must have a corresponding definition in order to retrieve fetchable and mutable fields.
The definition is an essential part in the process. It defines queryable and
mutable fields. Also, it allows you to apply transformers for only some data
with the getTransformers
methods. There's 5 kind of transformers to apply on :
list
: create a query to fetch many objects (User => users
)view
: create a query to retrieve one object (User => user
)drop
: create a mutation to delete an object (User => deleteUser
)store
: create a mutation to update an object (User => user
)batch
: create a mutation to update many object at once (User => users
)restore
: create a mutation to restore an object (User => restoreUser
)
By the default, the definition abstract class handles Eloquent model transformation.
A definition is composed from types. Our custom class extend the default
GraphQL\Type\Definition\Type
class in order to implement json
and datetime
availabled types.
Query
If you want create a query by hand, it's possible.
getResolver()
receives an array-argument with followed item:
root
1st argument given by webonyx library -GraphQL\Executor\Executor::resolveOrError()
args
2nd argument given by webonyx librarycontext
3rd argument given by webonyx libraryinfo
4th argument given by webonyx libraryfields
array of fields, that were fetched from query. Limited by depth inStudioNet\GraphQL\GraphQL::FIELD_SELECTION_DEPTH
with
array of relations, that could/should be eager loaded. NOTICE: Finding this relations happens ONLY, ifgetSource()
is defined - this method should return a class name of a associated root-type in query. IfgetSource()
is not defined, thenwith
will be always empty.
Mutation
Mutation are used to update or create data.
Pipeline
Pipeline are used to convert a definition into queryable and mutable operations. But, you can easily create your own and manage useful cases like asserting ACL before doing anything, etc.
Pipeline is implemented using the same Laravel Middleware format but pass as first argument the Eloquent Query Builder.
Create new pipe
With this sample, when you'll query posts
query, you'll only get viewer posts,
not all one. Also, you can specify arguments in the pipe, like following :
Require authorization
Currently you have a possibility to protect your own queries and mutations. You have to implement authorize()
method in your query/mutation, that return a boolean, that indicates, if requested query/mutation has to be executed. If method return false
, an UNAUTHORIZED
GraphQL-Error will be thrown.
Usage examples are in query and mutation above.
Protection of definition transformers are currently not implemented, but may be will in the future. By now you have to define your query/mutation yourself, and protect it then with logic in authorize()
.
Self documentation
A documentation generator is implemented with the package. By default, you can access it by navigate to /doc/graphql
. You can change this behavior within the configuration file. The built-in documentation is implemented from this repository.
Examples
Using filters
When declaring the getFilterable
array, you can define filters for fields.
You can either use a closure, an array, or give object of class implementing FilterInterface.
The closure (or the FilterInterface::updateBuilder
method) is then called
with:
- $builder : the current laravel query builder
- $value : the filter value
- $key : the filter key
You also may define graphql type for you filterable input field. By default Type::json()
is used. There are several
options to define the type (all examples are listed in following code-block):
- if you are using class that implements
TypedFilterInterface
, returned type from methodTypedFilterInterface::getType
is used; - if you are using closure, you have to define an array with keys
type
containing type you wish andresolver
containing closure; - if you define an array, and in
resolver
is passed an object of class with implementedTypedFilterInterface
, then type ofTypedFilterInterface::getType
will overwrite the type in an array keytype
; - in all other situations
Type::json()
will be used as default type
You can also use the predefined EqualsOrContainsFilter
like below.
This will execute a query : WHERE id = 1
This will execute a query : WHERE id in (1,2)
This will execute a query : WHERE name like '%santiago%'
Ordering (order_by
)
You can specify the order of the results (which calls Eloquent's orderBy
) with
the order_by
argument (which is a String[]
).
You can specify a direction by appending asc
(which is the default) or desc
to the order field :
You can specify multiple order_by
:
Pagination : limit (take
), offset (skip
)
You can limit the number of results with take
(Int
) :
You can skip some results with skip
(Int
) :
You can get useful pagination information :
Where :
totalCount
is the total number of resultspage
is the current page (based ontake
which is used as the page size)numPages
is the total number of pageshasNextPage
, true if there is a next pagehasPreviousPage
, true if there is a previous page
Mutation
Mutation: custom input fields
You can specify a "mutable" field which is not in the Eloquent Model, and define a custom method to it.
For a field named foo_bar
, the method has to be named inputFooBarField
, and
it has the Eloquent Model and the user input value as arguments.
Exemple (in Definition
) :
The input method is executed before the model is saved.
You can return an array with a "saved" callback, which will be executed post-save (which can be useful for eloquent relational models) :
N+1 Problem
The common question is, if graphql library solves n+1 problem. This occures, when graphql resolves relation. Often entities are fetched without relations, and when graphql query needs to fetch relation, for each fetched entity relation would be fetched from SQL separately. So instead of executing 2 SQL queries, you will get N+1 queries, where N is the count of results of root entity. In that example you would query only one relation. If you query more relations, then it becomes N^2+1 problem.
To solve it, Eloquent has already options to eager load relations. Transformers in this library use eager loading, depends on what you query.
Currently this smart detection works perfect only on View and List Transformers. Other transformers will be reworked soon.
Contribution
If you want participate to the project, thank you ! In order to work properly, you should install all dev dependencies and run the following commands before pushing in order to prevent bad PR :
All versions of laravel-graphql with dependencies
webonyx/graphql-php Version ^0.13.0
doctrine/dbal Version ^2.5
cache/array-adapter Version ^1.0