All Projects → slaypni → Type Graphql Dataloader

slaypni / Type Graphql Dataloader

Licence: mit
TypeGraphQL + DataLoader + TypeORM made easy

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Type Graphql Dataloader

Api
Stars: ✭ 18 (-75.34%)
Mutual labels:  graphql, apollo-server
Apollo Server Vercel
⚫ Production-ready Node.js GraphQL server for Vercel Serverless Functions
Stars: ✭ 69 (-5.48%)
Mutual labels:  graphql, apollo-server
Create Social Network
An educational project, demonstrating how to build a large scalable project with Javascript.
Stars: ✭ 853 (+1068.49%)
Mutual labels:  graphql, apollo-server
Dataloader
Implementation of Facebook's DataLoader in Golang
Stars: ✭ 703 (+863.01%)
Mutual labels:  graphql, dataloader
Api.gatsbyjs.org
The API for the Gatsby swag store.
Stars: ✭ 44 (-39.73%)
Mutual labels:  graphql, apollo-server
Graphql Yoga
🧘 Fully-featured GraphQL Server with focus on easy setup, performance & great developer experience
Stars: ✭ 6,573 (+8904.11%)
Mutual labels:  graphql, apollo-server
Graphql Modules
Enterprise Grade Tooling For Your GraphQL Server
Stars: ✭ 962 (+1217.81%)
Mutual labels:  graphql, apollo-server
Apollo Resolvers
Expressive and composable resolvers for Apollostack's GraphQL server
Stars: ✭ 428 (+486.3%)
Mutual labels:  graphql, apollo-server
Graphql Apq
🎯 Automatic persisted queries (APQ) for any GraphQL server.
Stars: ✭ 43 (-41.1%)
Mutual labels:  graphql, apollo-server
Fullstack Tutorial
🚀 The Apollo platform tutorial app
Stars: ✭ 1,007 (+1279.45%)
Mutual labels:  graphql, apollo-server
Gqlgen
go generate based graphql server library
Stars: ✭ 6,880 (+9324.66%)
Mutual labels:  graphql, dataloader
Typeorm Graphql Loader
A query builder to easily resolve nested fields and relations for TypeORM-based GraphQL servers
Stars: ✭ 47 (-35.62%)
Mutual labels:  graphql, dataloader
Graphql Cost Analysis
A Graphql query cost analyzer.
Stars: ✭ 527 (+621.92%)
Mutual labels:  graphql, apollo-server
Batch Loader
⚡️ Powerful tool for avoiding N+1 DB or HTTP queries
Stars: ✭ 812 (+1012.33%)
Mutual labels:  graphql, dataloader
Chatty
A WhatsApp clone with React Native and Apollo (Tutorial)
Stars: ✭ 481 (+558.9%)
Mutual labels:  graphql, apollo-server
Graphql Serverless
Sample project to guide the use of GraphQL and Serverless Architecture.
Stars: ✭ 28 (-61.64%)
Mutual labels:  graphql, dataloader
Apollo Errors
Machine-readable custom errors for Apollostack's GraphQL server
Stars: ✭ 405 (+454.79%)
Mutual labels:  graphql, apollo-server
Graphql Dataloader Boilerplate
Very simple boilerplate using GraphQL and DataLoader
Stars: ✭ 405 (+454.79%)
Mutual labels:  graphql, dataloader
Graphql Rust Demo
GraphQL Rust Demo
Stars: ✭ 37 (-49.32%)
Mutual labels:  graphql, apollo-server
Graphql Advanced Projection
Fully customizable Mongoose/MongoDB projection generator.
Stars: ✭ 46 (-36.99%)
Mutual labels:  graphql, apollo-server

TypeGraphQL-DataLoader

TypeGraphQL-DataLoader is a utility to use DataLoader with TypeGraphQL without fuss.

Install

npm install type-graphql-dataloader

The latest build is tested with the following packages:

  • type-graphql 1.1.0
  • apollo-server-express 2.18.2
  • (optional) typeorm 0.2.28

Getting Started

Apollo Server is the first-class supported server. If your application uses Apollo Server, pass ApolloServerLoaderPlugin() as a plugin when instantiating the server. This plugin is for set-up and clean-up against each request.

import { ApolloServerLoaderPlugin } from "type-graphql-dataloader";
import { getConnection } from "typeorm";

...

const apollo = new ApolloServer({
  schema,
  plugins: [
    ApolloServerLoaderPlugin({
      typeormGetConnection: getConnection,  // for use with TypeORM
    }),
  ],
});

...

With TypeORM

TypeORM is the first-class supported ORM. If your application uses TypeORM with TypeGraphQL, adding @TypeormLoader decorator to relation properties will solve N + 1 problem. When the fields are accessed by graphQL, batch loading will be performed using DataLoader under the hood.

@TypeormLoader takes a function which returns the target class as the first argument. it requires another function which takes original entity and returns target relation id(s) as the second argument.

import { ObjectType, Field, ID } from "type-graphql";
import { TypeormLoader } from "type-graphql-dataloader";
import { Entity, PrimaryGeneratedColumn, ManyToOne, RelationId } from "typeorm";
import { User } from "./User";

@ObjectType()
@Entity()
export class Photo {
  @Field((type) => ID)
  @PrimaryGeneratedColumn()
  id: number;

  @Field((type) => User)
  @ManyToOne((type) => User, (user) => user.photos)
  @TypeormLoader((type) => User, (photo: Photo) => photo.userId)
  user: User;

  @RelationId((photo: Photo) => photo.user)
  userId: number;
}
import { ObjectType, Field, ID } from "type-graphql";
import { TypeormLoader } from "type-graphql-dataloader";
import { Entity, PrimaryGeneratedColumn, OneToMany, RelationId } from "typeorm";
import { Photo } from "./Photo";

@ObjectType()
@Entity()
export class User {
  @Field((type) => ID)
  @PrimaryGeneratedColumn()
  id: number;

  @Field((type) => [Photo])
  @OneToMany((type) => Photo, (photo) => photo.user)
  @TypeormLoader((type) => Photo, (user: User) => user.photoIds)
  photos: Photo[];

  @RelationId((user: User) => user.photos)
  photoIds: number[];
}

Reduce SQL queries further

selfKey option can be set true against properties which have @OneToMany or @OneToOne without @JoinColumn. If selfKey is true, the second argument must be a function which takes target entity and returns relation id of the original entity. The use of this functionality may reduce SQL queries because of how TypeORM works.

@ObjectType()
@Entity()
export class User {

  ...

  @Field((type) => [Photo])
  @OneToMany((type) => Photo, (photo) => photo.user)
  @TypeormLoader((type) => Photo, (photo: Photo) => photo.userId, { selfKey: true })
  photos: Photo[];
}

With Custom DataLoader

It is possible to assign custom DataLoader to a field by adding @Loader decorator to the corresponding method with @FieldResolver. @Loader takes a batch load function which is passed to the DataLoader constructor. The decorated method should return a function which takes a DataLoader instance and returns Promise of loaded value(s).

import DataLoader from "dataloader";
import { groupBy } from "lodash";
import { Resolver, Query, FieldResolver, Root } from "type-graphql";
import { Loader } from "type-graphql-dataloader";
import { getRepository, In } from "typeorm";
import { Photo } from "./Photo";
import { User } from "./User";

@Resolver((of) => User)
export default class UserResolver {

  ...

  @FieldResolver()
  @Loader<number, Photo[]>(async (ids, { context }) => {  // batchLoadFn
    const photos = await getRepository(Photo).find({
      where: { user: { id: In([...ids]) } },
    });
    const photosById = groupBy(photos, "userId");
    return ids.map((id) => photosById[id] ?? []);
  })
  photos(@Root() root: User) {
    return (dataloader: DataLoader<number, Photo[]>) =>
      dataloader.load(root.id);
  }
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].