Dynamically build TypeORM queries based on GraphQL queries for NestJS and TypeORM
Report Bug
·
Request Feature
Table of Contents
In order to harness the true potential of NestJS, GraphQL, and TypeORM, I needed a way to dynamically fetch child relationships based on the GraphQL query coming in, without having to write a resolver specific to each entity and limited in depth. I went searching for a solution and found this thread. A solution had been posted by david-eos, but it wasn't functional enough to integrate easily into a proper NestJS + TypeORM + @nestjs/graphql project. I re-worked his solution into a portable and lightweight package generalizable enough to be used by anyone.
This plugin is light-weight and easy to install and use.
npm i --save perch-query-builder@latest
import {Args, Context, Info, Query, Resolver} from '@nestjs/graphql';
import {Repository} from 'typeorm';
import {InjectRepository} from "@nestjs/typeorm";
import {PerchQueryBuilder} from 'perch-query-builder';
import {BookArgs} from '../args';
import {Book} from '../entities';
@Resolver(of => Book)
export class BookResolver {
constructor(
@InjectRepository(Book),
private bookRepository: Repository<Book>,
) {}
@Query(of => [Book], {
name: `Book`,
description: `Generic Collection Query For Books`,
nullable: true,
})
async queryBooks(
@Context() ctx,
@Args() args: BookArgs,
@Info() info: GraphQLResolveInfo,
): Promise<Book[]> {
// Simply pass your entity's repository, and the GraphQLResolve Info
return await PerchQueryBuilder.find<Book>(this.bookRepository, info);
}
}
In order to add the ability to sort results by a given property, import the OrderByArgs
argument class and declare it as an argument in your resolver
option | type | description |
---|---|---|
_orderAscBy | string | Sorts the results as ascending from the value given |
_orderDescBy | string | Sorts the results as descending from the value given |
// rest of imports...
import {OrderByArgs} from "perch-query-builder";
// rest of resolver class...
async queryBooks(
@Context() ctx,
@Args() args: BookArgs,
// It is passed along side your other arguments
@Args() orderByArgs: OrderByArgs,
@Info() info: GraphQLResolveInfo,
): Promise<Book[]> {
// There is nothing else to do, since OrderByArgs is only present to satisfy strict argument declaration requirements
return await PerchQueryBuilder.find<Book>(this.bookRepository, info);
}
// rest of resolver class...
Us in your query
{
# Return Books sorted by title ascending
Book(_orderAscBy: "title") {
id
title
}
}
Pagination is simple, though in a future feature "cursor" based pagination will be available as described in the GraphQL website
option | type | description |
---|---|---|
_limit | integer | Sets the max results to return, maps to the TypeORM SelectQueryBuilder<T>.take(number) method |
_offset | integer | Sets the number of entities to skip before returning your query, maps to the TypeORM SelectQueryBuilder<T>.skip(number) method |
In order to add pagination to your resolver, add the PaginationArgs
argument class and declare it as an argument in your resolver
// rest of imports...
import {PaginationArgs} from "perch-query-builder";
// rest of resolver class...
async queryBooks(
@Context() ctx,
@Args() args: BookArgs,
// It is passed along side your other arguments
@Args() paginationArgs: PaginationArgs,
@Info() info: GraphQLResolveInfo,
): Promise<Book[]> {
// There is nothing else to do, since PaginationArgs is only present to satisfy strict argument declaration requirements
return await PerchQueryBuilder.find<Book>(this.bookRepository, info);
}
// rest of resolver class...
Us in your query
{
# Return only 5 Books starting from the 10th book
Book(_limit: 5, _offset: 10) {
id
title
}
}
See the open issues for a list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request.
Credit to david-eos for writing the base functionality.
Distributed under the MIT License.
Wesley Young - @FullstackAttack - [email protected]
Project Link: https://github.com/wesleyyoung/perch-query-builder