Ретрансляция GraphQL от ArraySlice - PullRequest
1 голос
/ 05 июня 2019

Нет документации о том, как реализовать метаинформацию массива (arrayLength и sliceStart) с помощью вспомогательной библиотеки graphql-relay-js в Facebook.

https://github.com/graphql/graphql-relay-js/issues/199

Мне удалосьчтобы заставить его работать, используя следующую реализацию, однако я предполагаю, что есть более простой / более правильный способ сделать это.

Извлечение строк и подсчет строк из базы данных

function transformRole(role: Role) {
    return { ...role, roleId: role.id };
}

async function getRolesSlice({ roleId, after, first, last, before }: any): Promise<[Role[], number]> {    
    const queryBuilder = repository.createQueryBuilder();

    if (roleId !== undefined) {
        queryBuilder.where('id = :roleId', { roleId });
    }

    if (before) {
        const beforeId = cursorToOffset(before);
        queryBuilder.where('id < :id', { id: beforeId });
    }

    if (after) {
        const afterId = cursorToOffset(after);
        queryBuilder.where({
            id: MoreThan(Number(afterId))
        });
    }

    if (first === undefined && last === undefined) {
        queryBuilder.orderBy('id', 'ASC');
    }

    if (first) {
        queryBuilder.orderBy('id', 'ASC').limit(first);
    }

    if (last) {
        queryBuilder.orderBy('id', 'DESC').limit(last);
    }

    return Promise.all([
        queryBuilder.getMany()
            .then(roles => roles.map(transformRole)),
        repository.count() // Total number of roles
    ]);
}

Распределитель ролей

resolve: (_, args) =>
            getRolesSlice(args)
                .then(([results, count]) => {
                    const firstId = results[0] && results[0].roleId;

                    let sliceStart = 0;
                    if (args.first) {
                        sliceStart = firstId;
                    }
                    if (args.last) {
                        sliceStart = Math.max(firstId - args.last, 0);
                    }
                    if (args.after && args.last) {
                        sliceStart += 1;
                    }
                    return connectionFromArraySlice(
                        results,
                        args,
                        {
                            arrayLength: count + 1,
                            sliceStart
                        }
                    );
                })
    },

Редактировать:

Это то, что я придумал, это немного чище и, кажется,работает правильно.

const initialize = () => {
    repository = getConnection().getRepository(Role);
}

function transformRole(role: Role) {
    return { ...role, roleId: role.id };
}

function getRolesSlice(args: any):
    Promise<[
        Role[],
        any,
        { arrayLength: number; sliceStart: number; }
    ]> {
    if (!repository) initialize();

    const { roleId, after, first, last, before } = args;

    const queryBuilder = repository.createQueryBuilder();

    if (roleId !== undefined) {
        queryBuilder.where('id = :roleId', { roleId });
    }

    if (before !== undefined) {
        const beforeId = cursorToOffset(before);
        queryBuilder.where({
            id: LessThan(beforeId)
       });
    }

    if (after !== undefined) {
        const afterId = cursorToOffset(after);
        queryBuilder.where({
            id: MoreThan(Number(afterId))
        });
    }

    if (first !== undefined) {
        queryBuilder.orderBy('id', 'ASC').limit(first);
    } else if (last !== undefined) {
        queryBuilder.orderBy('id', 'DESC').limit(last);
    } else {
        queryBuilder.orderBy('id', 'ASC');
    }

    return Promise.all([
        queryBuilder.getMany()
            .then(roles => roles.map(transformRole))
            .then(roles => last !== undefined ? roles.slice().reverse() : roles),
        repository.count()
    ]).then(([roles, totalCount]) =>
        [
            roles,
            args,
            {
                arrayLength: totalCount + 1,
                sliceStart: roles[0] && roles[0].roleId
            }
        ]
    );
}

// Resolver
roles: {
    type: rolesConnection,
    args: {
        ...connectionArgs,
        roleId: {
            type: GraphQLString
        }
    },
    resolve: (_, args) =>
        getRolesSlice(args)
            .then((slice) => connectionFromArraySlice(...slice))
},
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...