Skip to content

Latest commit

 

History

History
224 lines (173 loc) · 5.96 KB

@sortBy.md

File metadata and controls

224 lines (173 loc) · 5.96 KB

@sortBy

Probably the most powerful directive to provide sort (order by conditions) for your GraphQL queries.

"""
Use Input as Sort Conditions for the current Builder.
"""
directive @sortBy
on
    | ARGUMENT_DEFINITION

Basic usage

How to use (and generated GraphQL schema):

type Query {
    "You can use normal input type"
    users(order: UsersSort @sortBy): ID! @all

    "or `_` to generate type automatically 😛"
    comments(order: _ @sortBy): [Comment!]! @all
}

input UsersSort {
    id: ID!
    name: String!
}

type Comment {
    text: String
    user: User @belongsTo
}

type User {
    id: ID!
    name: String!
}

And:

query {
    # ORDER BY user.name ASC, text DESC
    comments(order: [
        {field: {user: {name: asc}}}
        {field: {text: desc}}
    ])
}

Input type auto-generation

As you can see in the example above you can use the special placeholder _ instead of real input. In this case, @sortBy will generate input automatically by the actual type of the query. Please check the main section of Input type auto-generation to learn more about general conversion rules.

Addition rules for Implicit type:

  • The field is a list of scalar/enum? - exclude

The @sortByIgnored can be used as Ignored marker.

"""
Marks that field/definition should be excluded.
"""
directive @sortByIgnored
on
    | ENUM
    | FIELD_DEFINITION
    | INPUT_FIELD_DEFINITION
    | INPUT_OBJECT
    | OBJECT
    | SCALAR

Operators

The package defines only one's own type. To extend/replace the list of its operators, you can use config and/or add directives to scalar/enum inside the schema. Directives is the recommended way and have priority over the config. Please see @searchBy for examples.

  • SortByOperatorsExtra / Operators::Extra - List of additional extra operators for all types. The list is empty by default.
  • SortByOperatorsDisabled / Operators::Disabled - Disabled operators.

Eloquent/Database

Order by random

It is also possible to sort records in random order, but it is not enabled by default. To enable it you just need to add Random/@sortByOperatorRandom operator/directive to Extra type:

extend scalar SortByOperatorsExtra
@sortByExtendOperators
@sortByOperatorRandom

or via config

<?php declare(strict_types = 1);

use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator;
use LastDragon_ru\LaraASP\GraphQL\SortBy\Operators as SortByOperators;
use LastDragon_ru\LaraASP\GraphQL\SortBy\Definitions\SortByOperatorRandomDirective;

/**
 * -----------------------------------------------------------------------------
 * GraphQL Settings
 * -----------------------------------------------------------------------------
 *
 * @var array{
 *      sort_by: array{
 *          operators: array<string, list<string|class-string<Operator>>>
 *      },
 *      } $settings
 */
$settings = [
    'sort_by'   => [
        'operators' => [
            SortByOperators::Extra => [
                SortByOperatorRandomDirective::class,
            ],
        ],
    ],
];

return $settings;

And after this, you can 🎉

query {
    # ORDER BY RANDOM()
    comments(order: [
        {random: yes}
    ])
}

NULLs ordering

NULLs order different in different databases. Sometimes you may want to change it. There is no default/built-it support in Laravel nor Lighthouse, but you can do it! :) Please note, not all databases have native NULLS FIRST/NULLS LAST support (eg MySQL and SQL Server doesn't). The additional ORDER BY clause with CASE WHEN will be used for these databases. It may be slow for big datasets.

Default ordering can be changed via config. You may set it for all directions if single value used, in this case NULL always be first/last:

<?php declare(strict_types = 1);

use LastDragon_ru\LaraASP\GraphQL\SortBy\Enums\Nulls;

/**
 * @var array{
 *      sort_by: array{
 *          nulls: Nulls|non-empty-array<value-of<Direction>, Nulls>|null,
 *      },
 *      } $settings
 */
$settings = [
    'sort_by' => [
        'nulls' => Nulls::First,
    ],
];

return $settings;

Or individually for each direction:

<?php declare(strict_types = 1);

use LastDragon_ru\LaraASP\GraphQL\SortBy\Enums\Direction;
use LastDragon_ru\LaraASP\GraphQL\SortBy\Enums\Nulls;

/**
 * @var array{
 *      sort_by: array{
 *          nulls: Nulls|non-empty-array<value-of<Direction>, Nulls>|null,
 *      },
 *      } $settings
 */
$settings = [
    'sort_by' => [
        'nulls' => [
            Direction::Asc->value  => Nulls::First,
            Direction::Desc->value => Nulls::Last,
        ],
    ],
];

return $settings;

The query is also supported and have highest priority (will override default settings):

query {
    # ORDER BY user.name ASC NULLS FIRST, text DESC
    comments(order: [
        {nullsFirst: {user: {name: asc}}}
        {field: {text: desc}}
    ])
}