Skip to content

Commit

Permalink
chore(examples): add relationships exaple (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
goldcaddy77 authored Jan 12, 2019
1 parent 3fb97f1 commit a158d3d
Show file tree
Hide file tree
Showing 21 changed files with 4,416 additions and 36 deletions.
2 changes: 0 additions & 2 deletions examples/1-simple-model/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
generated/*
!generated/index.ts
!generated/schema.ts
14 changes: 0 additions & 14 deletions examples/1-simple-model/.graphqlconfig.yml

This file was deleted.

2 changes: 1 addition & 1 deletion examples/1-simple-model/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Example 1 - User
# Example 1 - User Model

## Setup

Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion examples/1-simple-model/generated/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion examples/2-complex-example/.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
APP_HOST=localhost
APP_PORT=4100
TYPEORM_DATABASE=example1
TYPEORM_DATABASE=example2
TYPEORM_USERNAME=postgres
TYPEORM_PASSWORD=
2 changes: 0 additions & 2 deletions examples/2-complex-example/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
generated/*
!generated/index.ts
!generated/schema.ts
14 changes: 0 additions & 14 deletions examples/2-complex-example/.graphqlconfig.yml

This file was deleted.

2 changes: 1 addition & 1 deletion examples/2-complex-example/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Example 1 - User
# Example 2 - Complex Example

## Setup

Expand Down
5 changes: 5 additions & 0 deletions examples/3-relationships/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
APP_HOST=localhost
APP_PORT=4100
TYPEORM_DATABASE=example3
TYPEORM_USERNAME=postgres
TYPEORM_PASSWORD=
1 change: 1 addition & 0 deletions examples/3-relationships/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
generated/*
24 changes: 24 additions & 0 deletions examples/3-relationships/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Example 3 - Relationships

## Setup

Run `yarn bootstrap && yarn start`

## Bootstrapping the App

Running `yarn bootstrap` will do the following:

- Install packages
- Create the example DB
- Seed the database

## Running the App

To run the project, run `yarn start`. This will:

- Run the API server
- Open GraphQL Playground

## Example Queries/Mutations

You can find some examples in [examples.gql](./examples.gql)
33 changes: 33 additions & 0 deletions examples/3-relationships/examples.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
query {
users(orderBy: createdAt_DESC) {
id
firstName
posts {
id
title
createdAt
}
createdAt
}

posts(where: { userId_in: ["<fill in with user ID>"] }, orderBy: createdAt_DESC) {
id
title
userId
createdAt
}
}

mutation {
createUser(data: { firstName: "TestUser" }) {
id
firstName
createdAt
}

createPost(data: { title: "Hello World", userId: "<fill in with user ID>" }) {
id
title
createdAt
}
}
45 changes: 45 additions & 0 deletions examples/3-relationships/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "example1",
"version": "0.0.0",
"scripts": {
"//": "make sure to install top-level packages, too",
"bootstrap": "cd ../.. && yarn && cd - && yarn && yarn db:create",
"db:create": "createdbjs $(dotenv -p TYPEORM_DATABASE) 2>&1 || :",
"db:drop": "dropdbjs $(dotenv -p TYPEORM_DATABASE) 2>&1 || :",
"playground:open": "open http://localhost:$(dotenv -p APP_PORT)/graphql",
"start": "npm-run-all --parallel start:ts playground:open",
"start:ts": "ts-node --type-check src/index.ts"
},
"dependencies": {
"pgtools": "^0.3.0",
"reflect-metadata": "^0.1.12",
"typescript": "^3.2.2"
},
"devDependencies": {
"@types/express": "^4.16.0",
"@types/faker": "^4.1.4",
"@types/isomorphic-fetch": "^0.0.34",
"@types/jest": "^23.3.11",
"@types/node": "^10.12.18",
"dotenv-cli": "^1.4.0",
"faker": "^4.1.0",
"jest": "^23.6.0",
"npm-run-all": "^4.1.5",
"ts-jest": "^23.10.5",
"ts-node": "^7.0.1"
},
"jest": {
"transform": {
".ts": "ts-jest"
},
"testRegex": "\\.test\\.ts$",
"moduleFileExtensions": [
"ts",
"js"
],
"coveragePathIgnorePatterns": [
"/node_modules/",
"\\.test\\.ts$"
]
}
}
30 changes: 30 additions & 0 deletions examples/3-relationships/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'reflect-metadata';
import * as dotenv from 'dotenv';
import { Container } from 'typedi';

dotenv.config();

import { App } from '../../../src/';

async function bootstrap() {
const app = new App(
{
container: Container,
warthogImportPath: '../../../src' // Path written in generated classes
},
{
cache: true,
synchronize: true
}
);

await app.start();
}

bootstrap().catch((error: Error) => {
console.error(error);
if (error.stack) {
console.error(error.stack!.split('\n'));
}
process.exit(1);
});
12 changes: 12 additions & 0 deletions examples/3-relationships/src/post.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { BaseModel, ID, ManyToOne, Model, StringField } from '../../../src';

import { User } from './user.entity';

@Model()
export class Post extends BaseModel {
@StringField()
title?: string;

@ManyToOne(() => User, user => user.posts, { nullable: false })
user?: User;
}
53 changes: 53 additions & 0 deletions examples/3-relationships/src/post.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { GraphQLResolveInfo } from 'graphql';
import { Arg, Args, Ctx, FieldResolver, Mutation, Query, Resolver, Root } from 'type-graphql';
import { Repository } from 'typeorm';
import { InjectRepository } from 'typeorm-typedi-extensions';

import { BaseResolver, Context, StandardDeleteResponse } from '../../../src';
import { PostCreateInput, PostUpdateArgs, PostWhereArgs, PostWhereInput, PostWhereUniqueInput } from '../generated';

import { Post } from './post.entity';
import { User } from './user.entity';

// Note: we have to specify `Post` here instead of (of => Post) because for some reason this
// changes the object reference when it's trying to add the FieldResolver and things break
@Resolver(Post)
export class PostResolver extends BaseResolver<Post> {
constructor(@InjectRepository(Post) private readonly postRepository: Repository<Post>) {
super(Post, postRepository);
}

@FieldResolver(returns => User)
user(@Root() post: Post, @Ctx() ctx: Context): Promise<User> {
return ctx.dataLoader.loaders.Post.user.load(post);
}

@Query(returns => [Post])
async posts(
@Args() { where, orderBy, limit, offset }: PostWhereArgs,
@Ctx() ctx: Context,
info: GraphQLResolveInfo
): Promise<Post[]> {
return this.find<PostWhereInput>(where, orderBy, limit, offset);
}

@Query(returns => Post)
async post(@Arg('where') where: PostWhereUniqueInput): Promise<Post> {
return this.findOne<PostWhereUniqueInput>(where);
}

@Mutation(returns => Post)
async createPost(@Arg('data') data: PostCreateInput, @Ctx() ctx: Context): Promise<Post> {
return this.create(data, ctx.user.id);
}

@Mutation(returns => Post)
async updatePost(@Args() { data, where }: PostUpdateArgs, @Ctx() ctx: Context): Promise<Post> {
return this.update(data, where, ctx.user.id);
}

@Mutation(returns => StandardDeleteResponse)
async deletePost(@Arg('where') where: PostWhereUniqueInput, @Ctx() ctx: Context): Promise<StandardDeleteResponse> {
return this.delete(where, ctx.user.id);
}
}
12 changes: 12 additions & 0 deletions examples/3-relationships/src/user.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { BaseModel, Model, OneToMany, StringField } from '../../../src';

import { Post } from './post.entity';

@Model()
export class User extends BaseModel {
@StringField()
firstName?: string;

@OneToMany(() => Post, post => post.user)
posts?: Post[];
}
53 changes: 53 additions & 0 deletions examples/3-relationships/src/user.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { GraphQLResolveInfo } from 'graphql';
import { Arg, Args, Ctx, FieldResolver, Mutation, Query, Root, Resolver } from 'type-graphql';
import { Repository } from 'typeorm';
import { InjectRepository } from 'typeorm-typedi-extensions';

import { BaseResolver, Context, StandardDeleteResponse } from '../../../src';
import { UserCreateInput, UserUpdateArgs, UserWhereArgs, UserWhereInput, UserWhereUniqueInput } from '../generated';

import { User } from './user.entity';
import { Post } from './post.entity';

// Note: we have to specify `User` here instead of (of => User) because for some reason this
// changes the object reference when it's trying to add the FieldResolver and things break
@Resolver(User)
export class UserResolver extends BaseResolver<User> {
constructor(@InjectRepository(User) private readonly userRepository: Repository<User>) {
super(User, userRepository);
}

@FieldResolver()
posts(@Root() user: User, @Ctx() ctx: Context): Promise<Post[]> {
return ctx.dataLoader.loaders.User.posts.load(user);
}

@Query(returns => [User])
async users(
@Args() { where, orderBy, limit, offset }: UserWhereArgs,
@Ctx() ctx: Context,
info: GraphQLResolveInfo
): Promise<User[]> {
return this.find<UserWhereInput>(where, orderBy, limit, offset);
}

@Query(returns => User)
async user(@Arg('where') where: UserWhereUniqueInput): Promise<User> {
return this.findOne<UserWhereUniqueInput>(where);
}

@Mutation(returns => User)
async createUser(@Arg('data') data: UserCreateInput, @Ctx() ctx: Context): Promise<User> {
return this.create(data, ctx.user.id);
}

@Mutation(returns => User)
async updateUser(@Args() { data, where }: UserUpdateArgs, @Ctx() ctx: Context): Promise<User> {
return this.update(data, where, ctx.user.id);
}

@Mutation(returns => StandardDeleteResponse)
async deleteUser(@Arg('where') where: UserWhereUniqueInput, @Ctx() ctx: Context): Promise<StandardDeleteResponse> {
return this.delete(where, ctx.user.id);
}
}
23 changes: 23 additions & 0 deletions examples/3-relationships/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": "src",
"lib": ["dom", "es5", "es6", "es7", "esnext", "esnext.asynciterable"],
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"keyofStringsOnly": true,
"noImplicitAny": false,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": false, // Avoid noise in our resolvers when we use DI
"strict": true,
"strictNullChecks": true,
"types": ["jest", "isomorphic-fetch", "node"]
},
"include": ["src/**/*"],
"exclude": ["node_modules/**/*"]
}
Loading

0 comments on commit a158d3d

Please sign in to comment.