GraphQL中继连接来自ArraySlice

时间:2019-06-04 21:48:19

标签: graphql apollo graphql-relay

没有任何文档说明如何使用Facebook的graphql-relay-js帮助程序库实现数组元信息(arrayLength和sliceStart)。

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))
},

0 个答案:

没有答案