Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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
stylenone

...

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

  1. Create a webapi directory in your plugin directory. For example, for my local_todo plugin, this would be in /server/local/todo/webapi.

  2. Under the webapi directory, create an ajax directory.

  3. Create a schema.graphqls file under the ajax directory.

  4. In schema.graphqls, let’s define the todo_item type by adding the following:

    Code Block
    languagegraphql
    type local_todo_item {
        id: core_id
        title: String
        completed_at: core_date
    }

    This adds a new type with id, title and completed_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
    languagephp
    <?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 item item.php in the directory:

    Code Block
    languagephp
    <?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
languagegraphql
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
languagegraphql
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.

...