如何在NestJS(type-graphql)中使用“ graphql-to-mongodb”?

时间:2019-11-20 07:05:24

标签: graphql nestjs graphql-js type-graphql

我具有当前的解析器功能:

/********************
* recipe.resolver.ts
********************/
import { Args, Info, Query, Resolver, } from '@nestjs/graphql';
import { Recipe } from './recipe.model';
import { RecipeService } from './recipe.service';
import { FindAllArgs } from './entities/shared/dto/find-all.args';

@Resolver(of => Recipe)
export class RecipeResolver {
    constructor(private readonly recipeService: RecipeService) {}

    @Query(returns => [Recipe])
    async recipes(
        @Args() findAllArgs: FindAllArgs,
        @Info() info,
    ): Promise<Recipe[]> {
        return this.recipeService.findAll(info, findAllArgs);
    }
}

它利用了当前的服务功能:

/********************
* recipe.service.ts
********************/
import * as mongo from 'mongodb';
import { Injectable } from '@nestjs/common';
import { Recipe } from './recipe.model';
import { InjectCollection } from 'nest-mongodb';
import { FindAllArgs } from './entities/shared/dto/find-all.args';

@Injectable()
export class RecipeService {
    constructor(@InjectCollection('Recipe') private readonly recipeCollection: mongo.Collection) {}

    async findAll(info, findAllArgs: FindAllArgs): Promise<Recipe[]> {
        const queryAstFields = info.fieldNodes[0].selectionSet.selections;
        let idAbsent = true;
        const requestedFields = queryAstFields.reduce(
            (obj, item) => {
                const fieldName = item.name.value;
                if (fieldName === 'id') {
                    idAbsent = false;
                }
                return Object.assign(obj, { [fieldName]: true })
            }, {});
        if (idAbsent) {
            requestedFields._id = false;
        } else {
            delete requestedFields.id;
        }
        return this.recipeCollection.find({}, {projection: requestedFields, ...findAllArgs}).toArray();
    }
}
}

我的args DTO看起来像这样:

/********************
* find-all.args.ts
********************/

import { Min } from 'class-validator';
import { ArgsType, Field, Int } from 'type-graphql';
import { FindOneOptions } from 'mongodb';

@ArgsType()
export class FindAllArgs implements FindOneOptions {
    @Field(type => Int, {defaultValue: 0})
    @Min(0)
    skip?: number;

    @Field(type => Int, {defaultValue: 0})
    @Min(0)
    limit?: number;
}

如您所见,我已经在尝试使用projection函数中的options参数中的MongoDB的limitskipfind()。但是,我最近了解到graphql-to-mongodb npm package。看来它完全可以实现我正在做的事情。我想使用它;但是,我不确定如何将其合并到NestJS围绕GraphQL的解析器和type-graphql's参数的方式中。

我假设我必须在解析器中使用它,但是它具有getMongoDbQueryResolver和getGraphQLQueryArgs,并且我不确定如何添加它们。

存储库中有一个Apollo Example,但我不确定如何实现。

我以为我会尝试手动重做ArgsType中的所有内容,但是我遇到了为非numberstring或{ {1}};已经具有标量类型的那些。

boolean

我知道我可以定义自定义标量,但这是解决问题的方法吗?我可以找到的唯一自定义标量示例是/******************** * find-all.args.ts ********************/ import { Min } from 'class-validator'; import { ArgsType, Field, Int } from 'type-graphql'; import { FindOneOptions } from 'mongodb'; @ArgsType() export class FindAllArgs implements FindOneOptions { @Field(type => Int, { defaultValue: 0, description: 'Sets the limit of documents returned in the query.' }) @Min(0) limit?: number; // sort?: any[] | object; <-- What to do here? // projection?: object; <-- What to do here? @Field(type => Int, { defaultValue: 0, description: 'Set to skip N documents ahead in your query (useful for pagination).' }) @Min(0) skip?: number; // hint?: object; <-- What to do here? @Field({ defaultValue: false, description: 'Explain the query instead of returning the data.' }) explain?: boolean; @Field({ defaultValue: false, description: 'Specify if the cursor can timeout.' }) timeout?: boolean; @Field({ defaultValue: false, description: 'Specify if the cursor is tailable.' }) tailable?: boolean; @Field(type => Int, { defaultValue: 1000, description: 'Set the batchSize for the getMoreCommand when iterating over the query results.' }) @Min(0) batchSize?: number; @Field({ defaultValue: false, description: 'Only return the index key.' }) returnKey?: boolean; @Field({ nullable: true, description: 'Set minimum index bounds.' }) @Min(0) min?: number; @Field({ nullable: true, description: 'Set maximum index bounds.' }) @Min(0) max?: number; @Field({ defaultValue: false, description: 'Show disk location of results.' }) showDiskLoc?: boolean; @Field({ nullable: true, description: 'You can put a $comment field on a query to make looking in the profiler logs simpler.' }) comment?: string; @Field({ defaultValue: false, description: 'Return document results as raw BSON buffers.' }) raw?: boolean; @Field({ defaultValue: true, description: 'Promotes Long values to number if they fit inside the 53 bits resolution.' }) promoteLongs?: boolean; @Field({ defaultValue: true, description: 'Promotes BSON values to native types where possible, set to false to only receive wrapper types.' }) promoteValues?: boolean; @Field({ defaultValue: false, description: 'Promotes Binary BSON values to native Node Buffers.' }) promoteBuffers?: boolean; // readPreference?: ReadPreferenceOrMode; <-- What to do here? @Field({ defaultValue: false, description: 'Specify if the cursor should return partial results when querying against a sharded system.' }) partial?: boolean; @Field(type => Int, { nullable: true, description: 'Number of milliseconds to wait before aborting the query.' }) @Min(0) maxTimeMS?: number; } 的示例,因此必须定义returnTypeFunction,而且我不知道如何告诉它返回相同的对象。

这是提供的示例:

Date

例如,如何将/******************** * date.scalar.ts ********************/ import { CustomScalar, Scalar } from '@nestjs/graphql'; import { Kind } from 'graphql'; @Scalar('Date', type => Date) export class DateScalar implements CustomScalar<number, Date> { description = 'Date scalar type; Date objects contain a Number that represents milliseconds since 1 January 1970 UTC.'; parseValue(value: number): Date { return new Date(value); // value from the client } serialize(value: Date): number { return value.getTime(); // value sent to the client } parseLiteral(ast: any): Date { if (ast.kind === Kind.INT) { return new Date(ast.value); } return null; } } 转换为标量类型,例如示例中的类型?

0 个答案:

没有答案