Skip to content

Commit f3f62fe

Browse files
authored
Merge pull request #293 from andrew-demb/docs/228-bundle-docs
Add bundle documentation, ready for symfony.com (#228)
2 parents 581dd40 + faec569 commit f3f62fe

28 files changed

Lines changed: 2011 additions & 98 deletions

‎.github/workflows/docs.yaml‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: docs
2+
on:
3+
pull_request: ~
4+
push:
5+
branches:
6+
- master
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
11+
12+
jobs:
13+
doctor-rst:
14+
runs-on: ubuntu-latest
15+
name: Lint (DOCtor-RST)
16+
steps:
17+
- name: checkout
18+
uses: actions/checkout@v7
19+
20+
- name: doctor-rst
21+
uses: docker://oskarstark/doctor-rst:1.85.0
22+
with:
23+
args: docs --short --error-format=github

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/cache
66
.phpunit.result.cache
77
.phpstan-cache
8+
.doctor-rst.cache

‎.symfony.bundle.yaml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Configuration used by symfony.com to publish the docs of this bundle.
2+
# See https://github.com/liip/LiipImagineBundle/blob/2.x/.symfony.bundle.yaml for the documented format.
3+
branches: ["master"]
4+
maintained_branches: ["master"]
5+
doc_dir: "docs/"
6+
current_branch: "master"
7+
dev_branch: "master"
8+
dev_branch_alias: "7.x"

‎README.md‎

Lines changed: 39 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -4,117 +4,61 @@
44

55
# GraphQLite bundle
66

7-
Symfony bundle for the `thecodingmachine/graphqlite` package.
8-
It discovers your annotated controllers and types, builds the schema, exposes the `/graphql` endpoint through a PSR-7
9-
bridge (with optional upload handling), and keeps the Symfony request available as the GraphQL context.
7+
Symfony bundle for [GraphQLite](https://graphqlite.thecodingmachine.io): build a GraphQL API by adding PHP attributes
8+
(`#[Query]`, `#[Mutation]`, `#[Type]`, `#[Field]`...) to your classes. The bundle exposes the `/graphql` endpoint and
9+
integrates GraphQLite with Symfony services, Security, Validator, file uploads and cache.
1010

11-
Part of the bundle docs: https://graphqlite.thecodingmachine.io/docs/symfony-bundle
12-
13-
See [thecodingmachine/graphqlite](https://github.com/thecodingmachine/graphqlite).
11+
**Documentation: [docs/index.rst](docs/index.rst)**
1412

1513
## Requirements
1614

1715
- PHP 8.1+
18-
- Supports:
19-
- Symfony 6.4/7.0/8.0
20-
- GraphQLite ^8
21-
22-
## Installation
23-
24-
```bash
25-
composer require thecodingmachine/graphqlite-bundle
26-
```
27-
28-
Ensure the bundle is enabled (Symfony Flex does this automatically via `config/bundles.php` after `composer require`).
29-
30-
### Configure routes
31-
32-
Import the bundle routes to expose `/graphql`:
33-
34-
```yaml
35-
# config/routes/graphqlite.yaml
36-
graphqlite_bundle:
37-
resource: '@GraphQLiteBundle/Resources/config/routes.php'
38-
```
39-
40-
### Configure namespaces
41-
42-
Tell GraphQLite where to look for controllers and types:
43-
44-
```yaml
45-
# config/packages/graphqlite.yaml
46-
graphqlite:
47-
namespace:
48-
controllers: App\\GraphQL\\Controller
49-
types:
50-
- App\\GraphQL\\Type
51-
- App\\Entity
52-
```
53-
54-
## Quickstart
55-
56-
Create a controller with GraphQLite attributes:
57-
58-
```php
59-
<?php
60-
// src/GraphQL/Controller/HelloController.php
61-
namespace App\GraphQL\Controller;
62-
63-
use TheCodingMachine\GraphQLite\Annotations\Query;
16+
- Symfony 6.4, 7.x or 8.x
17+
- GraphQLite ^8
6418

65-
final class HelloController
66-
{
67-
#[Query]
68-
public function hello(string $name = 'world'): string
69-
{
70-
return sprintf('Hello %s', $name);
71-
}
72-
}
73-
```
19+
## Quick start
7420

75-
## Features
21+
1. Install the bundle (Symfony Flex enables it and creates its configuration):
7622

77-
- Auto-discovers controllers and types from configured namespaces and registers GraphQLite services, query providers,
78-
type mappers, and middleware through Symfony autoconfiguration
79-
- Ships a `/graphql` route that converts Symfony requests to PSR-7 and keeps the Symfony request in the GraphQL context
80-
- Passes the Symfony request as context to allow using them in queries/mutations
81-
- Supports multipart uploads when `graphql-upload` is installed
82-
- Integrates with Symfony Security for `#[Logged]`/`#[Right]` checks
83-
- Expose `login`/`logout` mutations plus a `me` query (opt-out)
84-
- Symfony Validator-based user input validation
85-
- Lets you cap introspection, query depth, and query complexity via configuration
86-
- Uses Symfony cache (APCu or PHP files) for schema caching
87-
- Includes a `graphqlite:dump-schema` console command to export GraphQL SDL
23+
```bash
24+
composer require thecodingmachine/graphqlite-bundle
25+
```
8826

89-
## Schema caching
27+
2. Tell GraphQLite where your GraphQL classes live:
9028

91-
Building the schema means reading every controller and type, so the result is cached. The
92-
`schema.auto_reload` option decides whether that cache is checked against your files on each request.
93-
It defaults to `'%kernel.debug%'`, so you see your changes while you work and deployed environments do
94-
not pay for the check.
29+
```yaml
30+
# config/packages/graphqlite.yaml
31+
graphqlite:
32+
namespace:
33+
controllers: App\GraphQL\Controller\
34+
types:
35+
- App\Entity\
36+
- App\GraphQL\Input\
37+
```
9538
96-
Set it yourself when an environment does not fit that rule, such as a staging server that runs with
97-
debug on but should still serve a cached schema:
39+
3. Write your first query and call `/graphql`:
9840

99-
```yaml
100-
# config/packages/graphqlite.yaml
101-
graphqlite:
102-
schema:
103-
auto_reload: false
104-
```
41+
```php
42+
// src/GraphQL/Controller/HelloController.php
43+
namespace App\GraphQL\Controller;
10544
106-
With `auto_reload: true` an edited controller or type shows up on the next request. With
107-
`auto_reload: false` the cached schema is trusted until the cache is cleared, so a deploy that changes
108-
a controller, a type or one of their attributes has to clear it. `cache:clear` does that. Note that
109-
with the APCu adapter the console and the web server each keep their own copy, so the PHP processes
110-
serving requests need restarting as well.
45+
use TheCodingMachine\GraphQLite\Annotations\Query;
11146
112-
## GraphiQL (playground)
47+
class HelloController
48+
{
49+
#[Query]
50+
public function hello(string $name = 'world'): string
51+
{
52+
return sprintf('Hello %s', $name);
53+
}
54+
}
55+
```
11356

114-
The bundle wires Overblog’s GraphiQL bundle if it is installed. See https://github.com/overblog/GraphiQLBundle for
115-
enabling the UI alongside the `/graphql` endpoint.
57+
Continue with the [getting started tutorial](docs/getting-started.rst).
11658

11759
## Development
11860

119-
- Tests: `vendor/bin/phpunit`
61+
- Tests: `vendor/bin/simple-phpunit`
12062
- Static analysis: `composer phpstan`
63+
- The code examples of `docs/` are tested: they must stay identical to the classes of `tests/DocsFixtures/`
64+
(see `tests/DocsExamplesTest.php`).

‎composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
},
6565
"extra": {
6666
"branch-alias": {
67-
"dev-master": "6.0.x-dev"
67+
"dev-master": "7.x-dev"
6868
}
6969
},
7070
"prefer-stable": true

‎config-template/packages/graphqlite.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Read more about GraphQLite available options at: https://graphqlite.thecodingmachine.io/docs/symfony-bundle
1+
# Read more about GraphQLite bundle options at: https://github.com/thecodingmachine/graphqlite-bundle/blob/master/docs/configuration.rst
22
graphqlite:
33
namespace:
44
controllers: App\GraphqlController\

‎docs/.doctor-rst.yaml‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
rules:
2+
american_english: ~
3+
avoid_repetetive_words: ~
4+
blank_line_after_anchor: ~
5+
blank_line_after_directive: ~
6+
blank_line_before_directive: ~
7+
correct_code_block_directive_based_on_the_content: ~
8+
ensure_bash_prompt_before_composer_command: ~
9+
ensure_exactly_one_space_before_directive_type: ~
10+
ensure_exactly_one_space_between_link_definition_and_link: ~
11+
ensure_link_definition_contains_valid_url: ~
12+
indention: ~
13+
lowercase_as_in_use_statements: ~
14+
max_blank_lines:
15+
max: 2
16+
no_app_console: ~
17+
no_blank_line_after_filepath_in_php_code_block: ~
18+
no_blank_line_after_filepath_in_yaml_code_block: ~
19+
no_composer_req: ~
20+
no_merge_conflict: ~
21+
no_namespace_after_use_statements: ~
22+
no_php_open_tag_in_code_block_php_directive: ~
23+
only_backslashes_in_namespace_in_php_code_block: ~
24+
only_backslashes_in_use_statements_in_php_code_block: ~
25+
ordered_use_statements: ~
26+
php_prefix_before_bin_console: ~
27+
replacement: ~
28+
short_array_syntax: ~
29+
space_between_label_and_link_in_doc: ~
30+
space_between_label_and_link_in_ref: ~
31+
title_underline_length_must_match_title_length: ~
32+
typo: ~
33+
unused_links: ~
34+
valid_use_statements: ~
35+
yaml_instead_of_yml_suffix: ~

‎docs/cache-and-performance.rst‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
Cache and Performance
2+
=====================
3+
4+
Reading the attributes of every class to build the schema is slow, so
5+
GraphQLite caches the result. The bundle configures this cache for you.
6+
7+
How the Schema Is Cached
8+
------------------------
9+
10+
The cache is stored in APCu when the extension is available (and enabled for
11+
the current SAPI), and in PHP files in the Symfony cache directory
12+
(``var/cache/<env>/``) otherwise.
13+
14+
The ``schema.auto_reload`` option (see :doc:`configuration`) decides when
15+
the cache is refreshed:
16+
17+
* ``true`` (default in ``dev``): GraphQLite checks your controller and type
18+
files on every request and refreshes the schema when one of them changed.
19+
Edit a class, reload, done;
20+
* ``false`` (default in ``prod``): the schema is built once and kept until
21+
the cache is cleared. This is the fastest mode.
22+
23+
Deploying to Production
24+
-----------------------
25+
26+
Run the usual cache commands as part of your deployment:
27+
28+
.. code-block:: terminal
29+
30+
$ php bin/console cache:clear --env=prod
31+
32+
The bundle registers its cache as a Symfony *cache clearer*, so
33+
``cache:clear`` also clears the GraphQLite cache.
34+
35+
.. caution::
36+
37+
APCu memory is separate for each PHP process pool: the console (CLI) cannot
38+
clear the APCu cache of your web server (PHP-FPM, FrankenPHP...). When the
39+
schema is cached in APCu, restart or reload PHP after deploying, as you
40+
probably already do for OPcache.
41+
42+
Performance Tips
43+
----------------
44+
45+
* Keep the ``namespace`` options narrow: list only the namespaces that
46+
contain GraphQL classes, rather than ``App\``. Fewer classes to scan means a
47+
faster cache warm-up and a faster ``dev`` environment;
48+
* avoid the "N+1 queries" problem when fetching related objects: use the
49+
`prefetch method`_ of GraphQLite to load them in batch;
50+
* fetch only what the client asked for with the `query plan`_;
51+
* limit the cost of the queries clients can send with
52+
``maximum_query_complexity`` and ``maximum_query_depth`` (see
53+
:doc:`security`).
54+
55+
.. _`prefetch method`: https://graphqlite.thecodingmachine.io/docs/prefetch-method
56+
.. _`query plan`: https://graphqlite.thecodingmachine.io/docs/query-plan

‎docs/commands.rst‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Console Commands
2+
================
3+
4+
Dumping the Schema
5+
------------------
6+
7+
The ``graphqlite:dump-schema`` command prints the GraphQL schema built from
8+
your code, in the GraphQL Schema Definition Language (SDL):
9+
10+
.. code-block:: terminal
11+
12+
$ php bin/console graphqlite:dump-schema
13+
14+
Use the ``--output`` (or ``-o``) option to write it to a file:
15+
16+
.. code-block:: terminal
17+
18+
$ php bin/console graphqlite:dump-schema --output=schema.graphql
19+
20+
Types and fields are sorted by name, so the output is stable. A few use cases:
21+
22+
* check that a class is picked up by GraphQLite after changing the
23+
``namespace`` configuration;
24+
* commit the schema file and review its changes in pull requests, to spot
25+
breaking changes of your API;
26+
* generate typed code for your frontend (TypeScript types, query hooks...)
27+
with tools such as `GraphQL Code Generator`_.
28+
29+
.. _`GraphQL Code Generator`: https://the-guild.dev/graphql/codegen

0 commit comments

Comments
 (0)