Skip to content

Commit 2d1ae37

Browse files
authored
GraphQL wrapper for HL API
1 parent 28cb7e6 commit 2d1ae37

File tree

11 files changed

+828
-11
lines changed

11 files changed

+828
-11
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@
8181
"twig/markdown-extra": "^3.7",
8282
"twig/string-extra": "^3.7",
8383
"twig/twig": "^3.7",
84-
"wapmorgan/unified-archive": "^1.2"
84+
"wapmorgan/unified-archive": "^1.2",
85+
"webonyx/graphql-php": "^15.5"
8586
},
8687
"require-dev": {
8788
"ext-xml": "*",

composer.lock

Lines changed: 75 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/api_doc.MD

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,56 @@ For example, if an endpoint returns a collection of items and each item has an `
103103

104104
For specific documentation on each endpoint, see the Swagger documentation at `/api.php/doc`.
105105
You may also make a request to `/api.php/doc` to get the raw Swagger JSON document if you set the `Content-Type` header to `application/json` or add `.json` to the end of the URL.
106+
107+
## GraphQL
108+
109+
The GLPI API is also available via a GraphQL wrapper at `/api.php/GraphQL`. Like all compliant GraphQL implementations, it is self documenting and accepts only POST requests.
110+
Since it is a wrapper around the REST API, that means that any object schema defined and available through the REST API is also available via GraphQL.
111+
It also means that authentication is the exact same as the rest of the API.
112+
The only difference is that you can access more properties in some cases via the GraphQL API.
113+
For example, when you request a list of cartridge models (`CartridgeItem`) via the REST API it returns the `id`, `name`, and `comment` properties for the associated printer models.
114+
When you request the data for cartridge models via GraphQL, it unlocks access to all the properties of the `PrinterModal` schema.
115+
This can reduce the number of requests that need to be made to the API in some cases.
116+
117+
The implementation of the GraphQL does not include any mutators. It is read-only.
118+
119+
The GraphQL API supports the same parameters as the REST API for filtering, sorting, and pagination.
120+
121+
Example:
122+
```graphql
123+
query {
124+
Ticket(limit: 1, filter: "name=ilike=test") {
125+
id
126+
name
127+
status {
128+
id
129+
name
130+
}
131+
}
132+
}
133+
```
134+
135+
You can explore the schemas using standard GraphQL requests like:
136+
```graphql
137+
query {
138+
__schema {
139+
types {
140+
name
141+
description
142+
fields {
143+
description
144+
type {
145+
name
146+
description
147+
}
148+
}
149+
}
150+
}
151+
}
152+
```
153+
154+
Alternatively, a REST API interface is available for the raw GraphQL type declarations at `/api.php/GraphQL/Schema` using a GET request.
155+
156+
As is standard with GraphQL, you MUST specify each property that you want to be returned.
157+
158+
For more information about GraphQL, see the [GraphQL documentation](https://graphql.org/learn/).

src/Api/HL/Controller/AssetController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,8 @@ private static function getGlobalAssetSchema($asset_schemas)
951951
'schema_name' => $schema_name,
952952
'itemtype' => $itemtype,
953953
];
954-
if ($shared_properties === []) {
955-
$shared_properties = Doc\Schema::flattenProperties($schema['properties']);
954+
if (empty($shared_properties)) {
955+
$shared_properties = $schema['properties'];
956956
// Remove array properties (complex handling may be required. No support added for now)
957957
$shared_properties = array_filter($shared_properties, static function ($property) {
958958
return !isset($property['type']) || $property['type'] !== Doc\Schema::TYPE_ARRAY;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/**
4+
* ---------------------------------------------------------------------
5+
*
6+
* GLPI - Gestionnaire Libre de Parc Informatique
7+
*
8+
* http://glpi-project.org
9+
*
10+
* @copyright 2015-2023 Teclib' and contributors.
11+
* @copyright 2003-2014 by the INDEPNET Development Team.
12+
* @licence https://www.gnu.org/licenses/gpl-3.0.html
13+
*
14+
* ---------------------------------------------------------------------
15+
*
16+
* LICENSE
17+
*
18+
* This file is part of GLPI.
19+
*
20+
* This program is free software: you can redistribute it and/or modify
21+
* it under the terms of the GNU General Public License as published by
22+
* the Free Software Foundation, either version 3 of the License, or
23+
* (at your option) any later version.
24+
*
25+
* This program is distributed in the hope that it will be useful,
26+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
27+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28+
* GNU General Public License for more details.
29+
*
30+
* You should have received a copy of the GNU General Public License
31+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
32+
*
33+
* ---------------------------------------------------------------------
34+
*/
35+
36+
namespace Glpi\Api\HL\Controller;
37+
38+
use Glpi\Api\HL\Doc as Doc;
39+
use Glpi\Api\HL\GraphQL;
40+
use Glpi\Api\HL\GraphQLGenerator;
41+
use Glpi\Api\HL\Middleware\CookieAuthMiddleware;
42+
use Glpi\Api\HL\Route;
43+
use Glpi\Api\HL\Router;
44+
use Glpi\Http\JSONResponse;
45+
use Glpi\Http\Request;
46+
use Glpi\Http\Response;
47+
48+
#[Route(path: '/GraphQL', priority: 1, tags: ['GraphQL'])]
49+
final class GraphQLController extends AbstractController
50+
{
51+
#[Route(path: '/', methods: ['POST'], security_level: Route::SECURITY_AUTHENTICATED)]
52+
#[Doc\Route(
53+
description: 'GraphQL API',
54+
)]
55+
public function index(Request $request): Response
56+
{
57+
return new JSONResponse(GraphQL::processRequest($request));
58+
}
59+
60+
#[Route(path: '/Schema', methods: ['GET'], security_level: Route::SECURITY_AUTHENTICATED)]
61+
#[Doc\Route(
62+
description: 'GraphQL API Schema',
63+
)]
64+
public function getSchema(Request $request): Response
65+
{
66+
$graphql_generator = new GraphQLGenerator();
67+
return new Response(200, [], $graphql_generator->getSchema());
68+
}
69+
}

0 commit comments

Comments
 (0)