183

A history of Symfony and GraphQL – Florent Destremau – Medium

 6 years ago
source link: https://medium.com/@FlorentDestrema/a-history-of-symfony-and-graphql-bc7370ef2d7e
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

You might have heard of a new sheriff in town: GraphQL. And then wondered how you could use it with *insert your non-JS language here*.

1*yRY2ZC35an7qInkvObGVew.png?q=20
a-history-of-symfony-and-graphql-bc7370ef2d7e

Sick montage skills here

TLDR;

If you are very lazy and just want a solution, here is my demo project, I’ll try to keep it updated: https://github.com/florentdestremau/graphql-example

What is GraphQL? Small reminder

Quick memo for those who don’t know what I’m talking about: GraphQL is a query language designed by Facebook to represent a modern way to communicated data between your front-end and back-end. For example if you wanted to query for the latest article from a blog, you’d write something like this as a front-end query

articles(limit: 10) {
id
title
excerpt
categories {
id
name
}
comments(limit: 3) {
id
author {
id
name
}
content
}
}

Did you see what happened here? A whole hierarchy of information was requested in a single request, and now we have all the information needed to display a whole bunch of stuff:

  • article titles with their link
  • the article categories with links too
  • the first articles’ comments, with a click-able link to the user’s profile
  • the content of the first 3 comments on the article.

So this is the very basic usage of GraphQL. But it’s only half of the implementation, you still need the back-end to handle the query interpretation and then return the actual data.

The back-end implementation in Symfony

If you are convinced by the simplicity and power of this type of query from the front-end (I sure am!), you probably wonder how it turns out in your back-end. So now is the time for me to announce that I am a Symfony developper and thus, while Facebook gave plenty of tools for NodeJS lovers, I had to rely on other libraries.

Meet youshido/graphql-bundle, the bundle that makes it all easy for you !

Note: there is an php port linked on the GraphQL website but at the time I was looking for a Symfony implementation, the youshido bundle was a better option for me, feel free to try the PHP library out !

The objective of this article is to explain how we use this bundle to easily set up you GraphQL API for a simple use: front-end widgets. The YoushidoGraphQLBundleprovides several classes to structure your GraphQL query tree.

  • Youshido\GraphQL\Schema\AbstractSchema to set up your basic architecture
  • Youshido\GraphQL\Type\Object\AbstractObjectType to set up query-out formatting (in all of my use cases I used the AbstractObjectType rather than the AbstractType )
  • Youshido\GraphQLBundle\Field\AbstractContainerAwareField to set up any query-in arguments and actions

For example you will have a tree structure like this:

Schema
- Query
- ArticlesField
- CommentsField
- UsersField
- CategoriesField
- Mutations
- PostArticleField

And each of these Fields will respectively return ArticleType, CommentType, UserType, CategoryType, or more exactly aListType of these.

The Fields

Here is what a simple ArticlesField would look like.

class ArticlesField extends AbstractContainerAwareField
{
public function resolve($value, array $args, ResolveInfo $info)
{
return $this->container->get('doctrine.orm.entity_manager')->getRepository(Article::class)->findAll();
} public function getType()
{
return new ListType(new ArticleType());
}
}

Notice the 2 key functions here.

  • resolve is the "controller", where you have access to the container and can call any service to retrieve the DATA
  • getType is the "template", you express what type of return format you allow for the GraphQL schema to have. We’ll get to that further down.

There is an extra function that you can use, it’s the build function:

public function build(FieldConfig $config)
{
$config->addArguments(
[
'published' => new BooleanType(),
]
);
}

This argument is exposed to the query, for instance you could query only articles that are published

articles(published: true) {
id
title
body
}

And then you can update your resolver:

public function resolve($value, array $args, ResolveInfo $info)
{
return $this->container
->get('doctrine.orm.entity_manager')
->getRepository(Article::class)
->findBy([
'published' => $args['published'],
]);
}

And there you go, filtered results !

The Types

So this was the “controller” part of the query, and now let’s get to the “templating” part. The Types (kind of a unfortunate naming, in my opinion, with the form Types as well, but hey I didn’t write it ¯\_(ツ)_/¯) are the classes that defines the JSON output for the file. Here is an example of what the ArticleType would be.

class ArticleType extends AbstractObjectType
{
public function build($config)
{
$config->addFields(
[
'id' => new IdType(),
'title' => new StringType(),
'body' => new StringType(),
'categories' => new ListType(new CategoryType()),
]
);
}
}

This way you define what fields are available to retrieve. Now this is a simple version, but you can add custom fields that require a bit more of an assistance. For instance to display the phone number of a user I would need to use the container:

As you can see the ResolveInfo entity has access to the container so you can use different services to render or simply do some logic stuff.

And there you go, a full GraphQL API!

Oh and one last thing, did I tell you that you had a live explorer at the /graphql/explorer ?

I actually made an API boilerplate with the bundle already installed:

Liked what you read ? Hit the 👏 button, I will write some more!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK