Skip to content

Instantly share code, notes, and snippets.

@hellos3b
Last active March 8, 2022 00:35
Show Gist options
  • Save hellos3b/6385a7f7da81da990fdc94eac2989722 to your computer and use it in GitHub Desktop.
Save hellos3b/6385a7f7da81da990fdc94eac2989722 to your computer and use it in GitHub Desktop.
GraphQL + TypeORM example
/** models/photos/Photo.ts */
import {getRepository, Entity, In, Column, RelationCount, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, RelationId, OneToMany} from "typeorm";
import { User, Bird, Like } from '@/models'
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 255 })
url: string;
@Column({ length: 1000, default: "" })
description: string;
@CreateDateColumn()
timestamp: Date;
@ManyToOne(type => User, user => user.photos, { eager: true })
takenBy: User;
@RelationId( (photo: Photo) => photo.takenBy)
takenById: number;
@ManyToOne(type => Bird, bird => bird.photos)
bird: Bird;
@RelationId( (photo: Photo) => photo.bird)
birdId: number;
@OneToMany(type => Like, like => like.photoId)
likes: Like;
@RelationCount( (photo: Photo) => photo.likes)
likesCount: number;
/** API */
/** Get all photos */
static findAll = () =>
getRepository(Photo)
.find()
/** Find photos taken by a specific user */
static takenByUser = (userId: number) =>
getRepository(Photo)
.find({ where: { takenBy: userId}})
static takenByUsers = (userIds: number[]) =>
getRepository(Photo)
.find({ where: { takenBy: In(userIds)}})
/** Get photos of a bird */
static ofBird = (bird: Bird) =>
getRepository(Photo)
.find({bird: bird})
static ofBirdFrom = (birdId: number, userId: number) =>
getRepository(Photo)
.find({
where: {
takenBy: userId,
bird: birdId
}
})
}
/** models/photos/PhotoQL.ts */
import {Photo, User, Bird} from '@/models'
import {Model, Query, Resolver} from '@/lib/modelQL'
import { gql } from 'apollo-server-core';
const schema = gql`
extend type Query {
photos: [Photo]
}
type Photo {
id: Int!
url: String!
description: String
timestamp: Date!
bird: Bird!
takenBy: User!
likesCount: Int
}
`
@Model("Photo", schema)
export class PhotoQL {
@Query()
async photos() {
return Photo.findAll()
}
@Resolver()
takenBy(photo: Photo) {
return photo.takenBy || User.findById(photo.takenById)
}
@Resolver()
bird(photo: Photo) {
return photo.bird || Bird.findById(photo.birdId)
}
}
/** models/user/User.ts */
/** The regular model files had the Type ORM definition and the db queries */
import { getRepository, Entity, RelationCount, Column, OneToMany, JoinTable, PrimaryGeneratedColumn, ManyToMany} from "typeorm";
import {Photo, Dex, Subscription} from '@/models'
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 60 })
name: string;
@Column({ length: 120, default: "" })
avatar: string;
@Column({ length: 120, default: "" })
coverImage: string;
@Column({ length: 60, default: "" })
city: string;
@OneToMany(type => Photo, photo => photo.takenBy)
photos: Photo[];
@RelationCount((user: User) => user.photos)
photosCount: number;
@ManyToMany(type => Dex, dex => dex.favorites)
@JoinTable()
dexes: Dex[];
@OneToMany(type => Subscription, sub => sub.user)
following: Subscription[]
@OneToMany(type => Subscription, sub => sub.following)
followers: Subscription[]
/** API */
static findById = async (id: number) =>
getRepository(User)
.findOne(id)
}
/** models/user/UserQL.ts */
/**
* My 'QL' files defined the schema and the resolvers
* I wrote a custom wrapper thing that auto merged schemas
**/
import {Model, Query, Resolver} from "@/lib/modelQL"
import {Photo, User, Dex, Subscription} from '@/models'
import { Activity } from "../activity/Activity";
import {gql} from 'apollo-server-express';
const schema = gql`
extend type Query {
user(id: Int): User
}
type User {
id: Int!
name: String!
city: String
avatar: String
coverImage: String
followers: [User]
following: [User]
dexes: [Dex]!
photos: [Photo]!
feed: [Photo]
photosCount: Int
}
`
@Model("User", schema)
export class UserQL {
@Resolver()
photos(user: User) {
return Photo.takenByUser(user.id)
}
@Resolver()
dexes(user: User) {
return Dex.favoritedByUser(user)
}
@Resolver()
following(user: User) {
return Subscription.getFollowing(user)
}
@Resolver()
followers(user: User) {
return Subscription.getFollowers(user)
}
@Resolver()
feed(user: User) {
return Activity.fromUser(user.id)
}
@Query()
user(_: void, args: {id: number}) {
return User.findById(args.id)
}
}
@daydreamerli
Copy link

Hi man, any suggestion on how to create the input to get the relations done and passing the right foreign key to the database, really appreciate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment