diff --git a/readme.md b/readme.md index ba8a520..e673b81 100644 --- a/readme.md +++ b/readme.md @@ -49,7 +49,7 @@ Congratulations, the server is running. 🚀 The most important parts are implemented and working properly but we have room for improvements. - [ ] Ordering -- [ ] Filtering +- [X] Filtering - [ ] Custom arguments example - [ ] Error handling - [ ] DataLoader @@ -205,3 +205,28 @@ Backward with cursor } } ``` + +With Filter + +```graphql +{ + products(last: 2, name: "Something") { + edges { + node { + id + name + description + createdAt + updatedAt + } + cursor + } + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + } +} +``` \ No newline at end of file diff --git a/src/modules/product/product.resolver.ts b/src/modules/product/product.resolver.ts index c2b6970..5eb36bb 100644 --- a/src/modules/product/product.resolver.ts +++ b/src/modules/product/product.resolver.ts @@ -13,8 +13,14 @@ export class ProductResolver { private service!: ProductService @Query(() => ProductConnection) - async products(@Args() args: ConnectionArgs): Promise { - return this.service.paginate(args) + async products( + @Args() args: ConnectionArgs, + @Arg('name', () => String, { nullable: true }) product_name: string + ): Promise { + return this.service.paginate( + args, + product_name ? { name: product_name } : undefined + ) } @Mutation(() => AddProductPayload) diff --git a/src/modules/product/product.service.ts b/src/modules/product/product.service.ts index e257131..15511da 100644 --- a/src/modules/product/product.service.ts +++ b/src/modules/product/product.service.ts @@ -1,5 +1,5 @@ import { Service } from 'typedi' -import { Repository } from 'typeorm' +import { FindConditions, Repository } from 'typeorm' import { InjectRepository } from 'typeorm-typedi-extensions' import { ProductEntity } from './product.entity' @@ -13,8 +13,11 @@ export class ProductService { @InjectRepository(ProductEntity) private readonly repository!: Repository - async paginate(args: ConnectionArguments): Promise { - return connectionFromRepository(args, this.repository) + async paginate( + args: ConnectionArguments, + filter?: FindConditions + ): Promise { + return connectionFromRepository(args, this.repository, filter) } async findById(id: string): Promise { diff --git a/src/relay/connection.factory.ts b/src/relay/connection.factory.ts index 9836f4c..57a569c 100644 --- a/src/relay/connection.factory.ts +++ b/src/relay/connection.factory.ts @@ -4,15 +4,18 @@ import { getOffsetWithDefault, offsetToCursor } from 'graphql-relay' -import { Repository } from 'typeorm' +import { FindConditions, Repository } from 'typeorm' export async function connectionFromRepository( args: ConnectionArguments, - repository: Repository + repository: Repository, + filterArg?: FindConditions ): Promise> { const { before, after, first, last } = args - const total = await repository.count() + const where = filterArg ? { where: filterArg } : undefined + + const total = await repository.count(where) // offsets const beforeOffset = getOffsetWithDefault(before, total) @@ -34,7 +37,7 @@ export async function connectionFromRepository( const take = Math.max(endOffset - startOffset, 1) // sql limit // records - const entities = await repository.find({ skip, take }) + const entities = await repository.find({ skip, take, where }) const edges = entities.map((entity, index) => ({ cursor: offsetToCursor(startOffset + index),