In this guide we’ll look at a plugin named local_todo
(which is the plugin todo
in the local
directory) as an example. If you just want to get started with a working example, start with the section “Create an internal query” and then skip to the “Using internal GraphQL in Tui components” section.
Table of Contents | ||
---|---|---|
|
...
In Totara, schemas are categorised based on their use cases. Each schema type - queries, mutations, types, etc. - follows specific rules about its availability and interactions with other schema types. Totara defines three four primary schema types: global, external, internal, and mobile.
External schema
The external schema is used for defining APIs It’s important to note, schema files defined within the types are not available in the other schema types. For example, if a type local_todo_item
was defined in the internal schema type, then it would not be available in the external, and vice versa. The only exception to this is the global schema, which is available to all schema types.
For more information about schema types, see Available APIs.
Global schema type
The global schema type is used for defining schema accessible to all schema types. It serves as the ‘root’ schema since it can be accessed by other schemas.
Global schemas are stored in the plugin's webapi/
directory. For example, in the local_todo
plugin, the external schema file would be located at:
Code Block |
---|
server/local/todo/webapi/schema.graphqls |
External schema type
The external schema type is used for defining schema accessible to external systems. It serves as the ‘root’ schema since it can be accessed by other schemasis isolated and not accessible to other schema types.
External schemas are stored in the plugin's webapi/
directory. For example, in the local_todo
plugin, the external schema file would be located at:
Code Block |
---|
server/local/todo/webapi/external/schema.graphqls |
Internal schema type
The internal schema type, also referred to as ajax
in the codebase, is designed for internal client operations. It is isolated and not accessible to other schema types.
...
For more information, refer to Totara's developer documentation or check the guide below on creating an internal query.
Mobile schema type
The mobile schema type is tailored for APIs used by the Totara Mobile app.
...
Code Block |
---|
server/local/todo/webapi/mobile/schema.graphqls |
Quick-start: Create an internal query
Create the schema
Create a
webapi
directory in your plugin directory. For example, for mylocal_todo
plugin, this would be in/server/local/todo/webapi
.Under the
webapi
directory, create anajax
directory.Create a
schema.graphqls
file under theajax
directory.In
schema.graphqls
, let’s define thetodo_item
type by adding the following:Code Block language graphql type local_todo_item { id: core_id title: String completed_at: core_date }
This adds a new type with
id
,title
andcompleted_at
, which we will have access to when using this type.objectNo
...
First we’ll create the directory for the query resolver by creating the following directory:
/server/local/todo/classes/webapi/resolver/query
Now let’s create the query resolver class,
items.php
in the directory we just created:Code Block language php <?php namespace local_todo\webapi\resolver\query; use core\webapi\execution_context; use core\webapi\query_resolver; use local_todo\entity\item; class items extends query_resolver { /** * @inheritDoc * @throws \coding_exception */ public static function resolve(array $args, execution_context $ec) { global $USER; $items = item::repository() ->where('user_id', $USER->id) ->order_by('id') ->get(); return ['items' => $items]; } }
In this file we’ve defined the query resolve and we’re using the ORM of
local_todo
to return a list of items.Now we create the type resolver directory
/server/local/todo/classes/webapi/resolver/type/
and the type resolver for itemitem.php
in the directory:Code Block language php <?php namespace local_todo\webapi\resolver\type; use core\webapi\execution_context; use core\webapi\type_resolver; class item extends type_resolver { /** * @param string $field - The field being requested * @param $source - In the case, source will be our `item` entity class as it's what's returned from the query resolver * @param array $args * @param execution_context $ec * @return mixed|void */ public static function resolve(string $field, $source, array $args, execution_context $ec) { return $source->$field; } }
Quick-start: Create an internal mutation (e.q. create, update, delete)
In this example we’ll create a mutation to update the title of a local_todo_item
.
...
Code Block | ||
---|---|---|
| ||
input local_todo_update_item_reference {
id: core_id!
} |
...
The GraphQL data is cached by default, so you may need to run purge in the PHP container your cache to see the latest changes. (See config.php
in your project root directory for more settings about cache.)
The mutation to run would be:
Code Block | ||
---|---|---|
| ||
mutation local_todo_update_item { local_todo_update_item( item_reference: {id: 8} input: {title: "My new title"} ) { item { id title } } } |
Next steps: Using internal GraphQL in Tui components
Please see our guide to creating your first component in Tui: Quick-start guide: Creating your first component. This guide covers how to create your first Tui component and also how to link it up to an GraphQL query.
...