Skip to content

Commit 6574fb1

Browse files
authored
Merge fa139a5 into dbf644a
2 parents dbf644a + fa139a5 commit 6574fb1

File tree

6 files changed

+202
-6
lines changed

6 files changed

+202
-6
lines changed

docs/input_types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,5 @@ In case you want to override the input type name, you can use the "name" attribu
125125
*/
126126
```
127127

128-
Notice that most of the type, the input type name will be completely transparent to you, so there is no real reason
128+
Most of the time, the input type name will be completely transparent to you, so there is no real reason
129129
to want to customize it.

docs/my_first_query.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
id: my-first-query
3+
title: Writing your first query
4+
sidebar_label: My first query
5+
---
6+
7+
## Creating a controller
8+
9+
In GraphQL-Controllers, GraphQL queries are creating by writing methods in "controller" classes.
10+
Each query method must be annotated with the `@Query` annotation.
11+
12+
Here is a sample of a "hello world" query:
13+
14+
```php
15+
namespace App\Controllers;
16+
17+
use TheCodingMachine\GraphQL\Controllers\Annotations\Query;
18+
19+
class MyController
20+
{
21+
/**
22+
* @Query
23+
*/
24+
public function hello(string $name): string
25+
{
26+
return 'Hello '.$name;
27+
}
28+
}
29+
```
30+
31+
- The `MyController` class does not need to extend any base class. For GraphQL-Controllers, a controller is simply a
32+
simple class.
33+
- The query method is annotated with a `@Query` annotation
34+
- The `MyController` class must be in the controllers namespace. You configured this namespace when you installed
35+
GraphqlControllers. By default, in Symfony, the controllers namespace is `App\Controller`.
36+
37+
<div class="alert alert-warning"><strong>Heads up!</strong> The <code>MyController</code> class must exist in the container of your
38+
application and the container identifier MUST be the fully qualified class name.</div>
39+
40+
<div class="alert alert-info">If you are using the Symfony bundle (or a framework with autowiring like Laravel), this
41+
is usually not an issue as the container will automatically create the controller entry if you do not explicitly
42+
declare it.</div>
43+
44+
## Testing the query
45+
46+
By default, the GraphQL endpoint is "/graphql".
47+
48+
The easiest way to test a GraphQL endpoint is to use [GraphiQL](https://github.com/graphql/graphiql) or
49+
[Altair](https://altair.sirmuel.design/) test clients.
50+
51+
These clients come with Chrome and Firefox plugins.
52+
53+
<div class="alert alert-info"><strong>Symfony users:</strong> If you are using the Symfony bundle, GraphiQL is also directly embedded.
54+
Simply head to <code>http://[path-to-my-app]/graphiql</code></div>
55+
56+
You can now perform a test query and get the answer:
57+
58+
<table style="width:100%; display: table">
59+
<tr>
60+
<td style="width:50%">
61+
<strong>Query</strong>
62+
<pre><code>{
63+
products {
64+
name
65+
}
66+
}</code></pre>
67+
</td>
68+
<td style="width:50%">
69+
<strong>Answer</strong>
70+
<pre><code class="hljs css language-json">{
71+
"data": {
72+
"products": [
73+
{
74+
"name": "Mouf"
75+
}
76+
]
77+
}
78+
}</code></pre>
79+
</td>
80+
</tr>
81+
</table>
82+
83+
84+
![](../img/query1.png)
85+
86+
Internally, GraphQL-Controllers created a query and added it to its internal type system.
87+
88+
If you are already used to GraphQL, you could represent this in "[Type language](https://graphql.org/learn/schema/#type-language)"
89+
like this:
90+
91+
```graphql
92+
Type Query {
93+
hello(name: String!): String!
94+
}
95+
```
96+
97+
But with GraphQL-Controllers you don't need to use the *Type language* at all. The philosophy of GraphQL-Controllers
98+
is that you do PHP code, you put annotations and GraphQL-Controllers is creating the GraphQL types for you. That means
99+
less boilerplate code!
100+
101+
Internally, GraphQL-Controllers will do the mapping between PHP types and GraphQL types.
102+
103+
## Creating your first type
104+
105+
So far, we simply declared a query. But we did not yet declare a type.
106+
107+
Let's assume you want to return a product:
108+
109+
```php
110+
use TheCodingMachine\GraphQL\Controllers\Annotations\Query;
111+
use TheCodingMachine\GraphQL\Controllers\Annotations\Mutation;
112+
113+
class ProductController
114+
{
115+
/**
116+
* @Query
117+
*/
118+
public function product(string $id): Product
119+
{
120+
// Some code that looks for a product and returns it.
121+
}
122+
}
123+
```
124+
125+
If you try to run a GraphQL query on this code, you immediately will face an error message:
126+
127+
<div class="alert alert-error">
128+
<code>For return type of ProductController::product, cannot map class "Product" to a known GraphQL type. Check your TypeMapper configuration.</code>
129+
</div>
130+
131+
This error tells you that your class `Product` is not a valid GraphQL type. To create a GraphQL type, you must add
132+
an annotation to this class.
133+
134+
```php
135+
TODO
136+
```
137+
138+
TODO @Type, @Field
139+
140+
<div class="alert alert-info"><strong>Heads up!</strong> If you are used to
141+
<a href="https://en.wikipedia.org/wiki/Domain-driven_design">Domain driven design</a>, you probably
142+
realize that the <code>Product</code> class is part of your "domain". GraphQL annotations are adding some serialization logic
143+
that is out of scope of the domain. These are "just" annotations and for most project, this is the fastest and
144+
easiest route. If you feel that GraphQL annotations do not belong to the domain, or if you cannot modify the class
145+
directly (maybe because it is part of a third party library), there is another way to create types without annotating
146+
the domain class. We will explore that in the next chapter.
147+
</div>
148+
149+
150+
151+
152+
153+
154+
155+
TODO: working with annotations.
156+
Doctrine annotations => do not forget the "use".
157+
Advice: use a plugin for your IDE
158+
Eclipse: https://marketplace.eclipse.org/content/doctrine-plugin
159+
PHPStorm: https://plugins.jetbrains.com/plugin/7320-php-annotations

docs/symfony-bundle.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ Create a configuration file in `config/packages/graphql_controllers.yaml`:
6666
graphql_controllers:
6767
namespace:
6868
controllers: App\Controller\
69-
types: App\Types\
69+
types:
70+
- App\Types\
71+
- App\Models\
7072
debug:
7173
# Include exception messages in output when an error arises
7274
INCLUDE_DEBUG_MESSAGE: false
@@ -79,8 +81,11 @@ graphql_controllers:
7981
RETHROW_UNSAFE_EXCEPTIONS: true
8082
```
8183
82-
The 'graphqlcontrollers.namespace.controllers' configuration variable is the namespace that will store your GraphQL controllers.
83-
The 'graphqlcontrollers.namespace.types' configuration variable is the namespace that will store your GraphQL types and factories.
84+
The 'graphqlcontrollers.namespace.controllers' configuration variable is the namespace(s) that will store your GraphQL controllers.
85+
The 'graphqlcontrollers.namespace.types' configuration variable is the namespace(s) that will store your GraphQL types and factories.
86+
87+
For both 'graphqlcontrollers.namespace.controllers' and 'graphqlcontrollers.namespace.types', you can pass a string (the namespace to target)
88+
or an array of strings if you have several namespaces to track.
8489
8590
## Configure the bundle
8691

website/sidebars.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"docs": {
33
"Installation": ["getting-started", "symfony-bundle", "other-frameworks"],
4-
"Usage": ["input-types", "file-uploads", "custom-output-types"]
4+
"Usage": ["my-first-query", "input-types", "file-uploads", "custom-output-types"]
55
}
66
}

website/static/css/custom.css

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,36 @@
1313
}
1414

1515
@media only screen and (min-width: 1500px) {
16-
}
16+
}
17+
18+
.alert {
19+
padding: 20px;
20+
color: white;
21+
margin-bottom: 15px;
22+
}
23+
24+
.alert a {
25+
color: #ddd;
26+
font-weight: bold;
27+
}
28+
29+
.alert a:hover {
30+
color: #bbb;
31+
}
32+
33+
34+
.alert.alert-success {
35+
background-color: #4CAF50;
36+
}
37+
38+
.alert.alert-info {
39+
background-color: #2196F3;
40+
}
41+
42+
.alert.alert-warning {
43+
background-color: #ff9800;
44+
}
45+
46+
.alert.alert-error {
47+
background-color: #f44336;
48+
}

website/static/img/query1.png

32.3 KB
Loading

0 commit comments

Comments
 (0)