- Notifications
You must be signed in to change notification settings - Fork1
Pure PHP implementation of GraphQL Server – Symfony Bundle
License
99designs/GraphQLBundle
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This is a bundle based on the purePHP GraphQL Server implementation
This bundle provides you with:
- Full compatibility with theRFC Specification for GraphQL
- Agile object oriented structure to architect your GraphQL Schema
- Intuitive Type system that allows you to build your project much faster and stay consistent
- Built-in validation for the GraphQL Schema you develop
- Well documented classes with a lot of examples
- Automatically created endpoint /graphql to handle requests
There are simple demo application to demonstrate how we build our API, seeGraphQLDemoApp.
We assume you havecomposer
, if you're not – install it from theofficial website.
If you need any help installing Symfony framework – here's the linkhttp://symfony.com/doc/current/book/installation.html.
Shortcut to install Symfony:
composer create-project symfony/framework-standard-edition my_project_name
Once you have your composer up and running – you're ready to install the GraphQL Bundle.
Go to your project folder and run:
composer require youshido/graphql-bundle
Then enable bundle in yourapp/AppKernel.php
newYoushido\GraphQLBundle\GraphQLBundle(),
Add the routing reference to theapp/config/routing.yml
:
graphql:resource:"@GraphQLBundle/Controller/"
or
graphql:resource:"@GraphQLBundle/Resources/config/route.xml"
If you don't have a web server configured you can use a bundled version, simply runphp bin/console server:run
.
Let's check if you've done everything right so far – try to access urllocalhost:8000/graphql
.
You should get a JSON response with the following error:
{"errors":[{"message":"Schema class does not exist"}]}
That's because there was no GraphQL Schema specified for the processor yet. You need to create a GraphQL Schema class and set it inside yourapp/config/config.yml
file.
There is a way where you can use inline approach and do not create a Schema class, in order to do that you have to define your own GraphQL controller and use a
->setSchema
method of the processor to set the Schema.
The fastest way to create a Schema class is to use a generator shipped with this bundle:
php bin/console graphql:configure AppBundle
HereAppBundle is a name of the bundle where the class will be generated in.
You will be requested for a confirmation to create a class.
After you've added parameters to the config file, try to access the following link in the browser –http://localhost:8000/graphql?query={hello(name:World)}
Alternatively, you can execute the same request using CURL client in your console
curl http://localhost:8000/graphql --data "query={ hello(name: \"World\") }"
Successful response from a test Schema will be displayed:
{"data":{"hello":"world!"}}
That means you have GraphQL Bundle for the Symfony Framework configured and now can architect your GraphQL Schema:
Next step would be to link assets for GraphiQL Explorer by executing:
php bin/console assets:install --symlink
Now you can access it athttp://localhost:8000/graphql/explorer
AbstractContainerAwareField class used for auto passing container to field, add ability to use container in resolve function:
class RootDirFieldextends AbstractContainerAwareField{/** * @inheritdoc */publicfunctiongetType() {returnnewStringType(); }/** * @inheritdoc */publicfunctionresolve($value,array$args,ResolveInfo$info) {return$this->container->getParameter('kernel.root_dir'); }/** * @inheritdoc */publicfunctiongetName() {return'rootDir'; }
Ability to pass service method as resolve callable:
$config->addField(newField(['name' =>'cacheDir','type' =>newStringType(),'resolve' => ['@resolve_service','getCacheDir']]))
You can use the Symfony Event Dispatcher to get control over specific events which happen when resolving graphql queries.
namespace ...\...\..;useYoushido\GraphQL\Event\ResolveEvent;useSymfony\Component\EventDispatcher\EventSubscriberInterface;class MyGraphQLResolveEventSubscriberimplements EventSubscriberInterface{publicstaticfunctiongetSubscribedEvents() {return ['graphql.pre_resolve' =>'onPreResolve','graphql.post_resolve' =>'onPostResolve' ]; }publicfunctiononPreResolve(ResolveEvent$event) {//$event->getFields / $event->getAstFields().. }publicfunctiononPostResolve(ResolveEvent$event) {//$event->getFields / $event->getAstFields().. }}
Now configure you subscriber so events will be caught. This can be done in Symfony by either XML, Yaml or PHP.
<serviceid="my_own_bundle.event_subscriber.my_graphql_resolve_event_subscriber"class="...\...\...\MyGraphQLResolveEventSubscriber"><tagname="graphql.event_subscriber" /></service>
Bundle provides two ways to guard your application: using black/white operation list or using security voter.
Used to guard some root operations. To enable it you need to write following in your config.yml file:
graphql:#...security:black_list:['hello']# or white_list: ['hello']
Used to guard any field resolve and support two types of guards: root operation and any other field resolving (including internal fields, scalar type fields, root operations). To guard root operation with your specified logic you need to enable it in configuration and useSecurityManagerInterface::RESOLVE_ROOT_OPERATION_ATTRIBUTE
attribute. The same things need to do to enable field guard, but in this case useSecurityManagerInterface::RESOLVE_FIELD_ATTRIBUTE
attribute.Official documentation about voters.
Note: Enabling field security lead to a significant reduction in performance
Config example:
graphql:security:guard:field:true# for any field securityoperation:true# for root level security
Voter example (add in to yourservices.yml
file with tagsecurity.voter
):
useSymfony\Component\Security\Core\Authentication\Token\TokenInterface;useSymfony\Component\Security\Core\Authorization\Voter\Voter;useYoushido\GraphQL\Execution\ResolveInfo;useYoushido\GraphQLBundle\Security\Manager\SecurityManagerInterface;class GraphQLVoterextends Voter{/** * @inheritdoc */protectedfunctionsupports($attribute,$subject) {returnin_array($attribute, [SecurityManagerInterface::RESOLVE_FIELD_ATTRIBUTE, SecurityManagerInterface::RESOLVE_ROOT_OPERATION_ATTRIBUTE]); }/** * @inheritdoc */protectedfunctionvoteOnAttribute($attribute,$subject,TokenInterface$token) {// your own validation logic hereif (SecurityManagerInterface::RESOLVE_FIELD_ATTRIBUTE ==$attribute) {/** @var $subject ResolveInfo */if ($subject->getField()->getName() =='hello') {returnfalse; }returntrue; }elseif (SecurityManagerInterface::RESOLVE_ROOT_OPERATION_ATTRIBUTE ==$attribute) {/** @var $subject Query */if ($subject->getName() =='__schema') {returntrue; } } }}
To rungraphiql extension just try to access tohttp://your_domain/graphql/explorer
All detailed documentation is available on the main GraphQL repository – http://github.com/youshido/graphql/.
About
Pure PHP implementation of GraphQL Server – Symfony Bundle
Resources
License
Stars
Watchers
Forks
Packages0
Languages
- PHP51.4%
- CSS41.3%
- Twig7.3%