Package Exports
- nestjs-graphql-easy
- nestjs-graphql-easy/dist-lib/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (nestjs-graphql-easy) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
NestJS
Description
Nest framework TypeScript starter repository.
Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
NestJS-GraphQL-Easy
Installation
npm i nestjs-graphql-easy
Usage
Important!
- The typeorm model and the graphql object must be the same class.
- Decorators
PolymorphicColumn
,Column
,Entity
,CreateDateColumn
,UpdateDateColumn
,PrimaryColumn
,PrimaryGeneratedColumn
fromtypeorm
must be imported fromnestjs-graphql-easy
- Decorators
Field
(only for columns from tables),ObjectType
,Query
,Mutation
,ResolveField
fromgraphql
must be imported fromnestjs-graphql-easy
- Points 2 and 3 are caused by the fact that it is necessary to collect data for auto-generation of filters and sorts, as well as not to deal with casting the names
graphql field <-> class property <-> typeorm column
andgraphql object <-> class name < -> typeorm table
(imported decorators fromnestjs-graphql-easy
removed the ability to set a name)
- Decorators
Filter
,Order
andPagination
fromnestjs-graphql-easy
work only with loader typesELoaderType.MANY
andELoaderType.ONE_TO_MANY
Entity/Object basic example
import { ID } from '@nestjs/graphql';
import { Index, OneToMany } from 'typeorm';
import {
ObjectType,
Field,
Column,
Entity,
CreateDateColumn,
UpdateDateColumn,
PrimaryGeneratedColumn
} from 'nestjs-graphql-easy';
import { Book } from '../book/book.entity';
@ObjectType()
@Entity()
export class Author {
@Field(() => ID, { filterable: true, sortable: true })
@PrimaryGeneratedColumn('uuid')
public id: string;
@Field(() => Date)
@CreateDateColumn({
type: 'timestamp without time zone',
default: () => 'CURRENT_TIMESTAMP',
})
public created_at: Date;
@Field(() => Date)
@UpdateDateColumn({
type: 'timestamp without time zone',
default: () => 'CURRENT_TIMESTAMP',
})
public updated_at: Date;
@Field(() => String, { filterable: true, sortable: true })
@Column()
@Index({ unique: true })
public name: string;
@OneToMany(() => Book, (book) => book.author, { onDelete: 'CASCADE' })
public books: Book[];
}
Resolver basic example
import { Args, Context, GraphQLExecutionContext, ID, Parent, Resolver } from '@nestjs/graphql';
import {
Query,
ResolveField,
ELoaderType,
Loader,
Filter,
Order,
Pagination
} from 'nestjs-graphql-easy';
import { Book } from '../book/book.entity';
import { Author } from './author.entity';
import { AuthorService } from './author.service';
@Resolver(() => Author)
export class AuthorResolver {
constructor(private readonly authorService: AuthorService) {}
@Query(() => [Author])
public async authors(
@Loader({
loader_type: ELoaderType.MANY,
field_name: 'authors',
entity: () => Author,
entity_fk_key: 'id',
}) field_alias: string,
@Filter(() => Author) _filter: unknown,
@Order(() => Author) _order: unknown,
@Pagination() _pagination: unknown,
@Context() ctx: GraphQLExecutionContext
) {
return await ctx[field_alias];
}
@ResolveField(() => [Book], { nullable: true })
public async books(
@Parent() author: Author,
@Loader({
loader_type: ELoaderType.ONE_TO_MANY,
field_name: 'books',
entity: () => Book,
entity_fk_key: 'author_id',
entity_where: {
query: 'book.is_private = :is_private',
params: { is_private: false },
},
}) field_alias: string,
@Filter(() => Book) _filter: unknown,
@Order(() => Book) _order: unknown,
@Context() ctx: GraphQLExecutionContext
): Promise<Book[]> {
return await ctx[field_alias].load(author.id);
}
}
Query basic example
query {
authors(
WHERE: { id: { NULL: false }, name: { ILIKE: "Author" } }
ORDER: { id: { SORT: ASC } }
PAGINATION: { page: 0, per_page: 10 }
) {
id
name
books(ORDER: { created_at: { SORT: DESC } }) {
id
title
}
}
}
Entity/Object with polymorphic relation example
import { ID } from '@nestjs/graphql';
import { Index, JoinColumn, ManyToOne } from 'typeorm';
import {
Field,
ObjectType,
PolymorphicColumn,
Column,
Entity,
CreateDateColumn,
UpdateDateColumn,
PrimaryGeneratedColumn
} from 'nestjs-graphql-easy';
import { Section } from '../section/section.entity';
@ObjectType()
@Entity()
export class Item {
@Field(() => ID, { filterable: true, sortable: true })
@PrimaryGeneratedColumn('uuid')
public id: string;
@Field(() => Date)
@CreateDateColumn({
type: 'timestamp without time zone',
default: () => 'CURRENT_TIMESTAMP',
})
public created_at: Date;
@Field(() => Date)
@UpdateDateColumn({
type: 'timestamp without time zone',
default: () => 'CURRENT_TIMESTAMP',
})
public updated_at: Date;
@Field(() => ID, { filterable: true, sortable: true })
@Index()
@Column('uuid', { nullable: false })
public section_id: string;
@ManyToOne(() => Section, { nullable: false })
@JoinColumn({ name: 'section_id' })
public section: Section;
@Field(() => ID, { filterable: true, sortable: true })
@Index()
@Column('uuid', { nullable: false })
@PolymorphicColumn()
public itemable_id: string;
@Field(() => String, { filterable: true, sortable: true })
@Index()
@Column({ nullable: false })
@PolymorphicColumn()
public itemable_type: string;
}
Polymorphic union type example
import { createUnionType } from '@nestjs/graphql';
import { ItemImage } from '../item-image/item-image.entity';
import { ItemText } from '../item-text/item-text.entity';
export const ItemableType = createUnionType({
name: 'ItemableType',
types: () => [ItemText, ItemImage],
resolveType(value) {
if (value instanceof ItemText) {
return ItemText;
} else if (value instanceof ItemImage) {
return ItemImage;
}
},
});
Resolver with polymorphic relation example
import { Args, Context, GraphQLExecutionContext, ID, Parent, Resolver } from '@nestjs/graphql';
import {
Query,
ResolveField,
ELoaderType,
Loader,
Filter,
Order,
Pagination
} from 'nestjs-graphql-easy';
import { Book } from '../book/book.entity';
import { Section } from '../section/section.entity';
import { ItemText } from '../item-text/item-text.entity';
import { ItemImage } from '../item-image/item-image.entity';
import { Item } from './item.entity';
import { ItemService } from './item.service';
import { ItemableType } from './item.itemable';
@Resolver(() => Item)
export class ItemResolver {
constructor(private readonly itemService: ItemService) {}
@Query(() => [Item])
public async items(
@Loader({
loader_type: ELoaderType.MANY,
field_name: 'items',
entity: () => Item,
entity_fk_key: 'id',
}) field_alias: string,
@Filter(() => Item) _filter: unknown,
@Order(() => Item) _order: unknown,
@Pagination() _pagination: unknown,
@Context() ctx: GraphQLExecutionContext
) {
return await ctx[field_alias];
}
@ResolveField(() => Book, { nullable: false })
public async section(
@Parent() item: Item,
@Loader({
loader_type: ELoaderType.MANY_TO_ONE,
field_name: 'section',
entity: () => Section,
entity_fk_key: 'id',
}) field_alias: string,
@Context() ctx: GraphQLExecutionContext
): Promise<Book> {
return await ctx[field_alias].load(item.section_id);
}
@ResolveField(() => ItemableType, { nullable: true })
public async itemable(
@Parent() item: Item,
@Loader({
loader_type: ELoaderType.POLYMORPHIC,
field_name: 'itemable',
entity: () => ItemableType,
entity_fk_key: 'id',
entity_fk_type: 'itemable_type',
}) field_alias: string,
@Context() ctx: GraphQLExecutionContext
) {
return await ctx[field_alias].load(item.itemable_id);
}
}
Query with polymorphic relation example
query {
items(
WHERE: { id: { NULL: false } }
ORDER: { id: { SORT: ASC } }
PAGINATION: { page: 0, per_page: 10 }
) {
id
itemable_id
itemable_type
itemable {
__typename
... on ItemText {
id
value
}
... on ItemImage {
id
file_url
created_at
}
}
}
}