Bird
Raised Fist0
NestJSframework~8 mins

Relations (OneToMany, ManyToOne, ManyToMany) in NestJS - Performance & Optimization

Choose your learning style10 modes available
Performance: Relations (OneToMany, ManyToOne, ManyToMany)
MEDIUM IMPACT
This affects database query performance and server response time, impacting how fast data loads and updates in the app.
Fetching related data with relations in NestJS using TypeORM
NestJS
const users = await userRepository.find({ relations: ['posts'] });
Fetches users and their posts in a single query using JOIN, reducing database calls.
📈 Performance GainSingle query regardless of number of users, greatly reducing response time.
Fetching related data with relations in NestJS using TypeORM
NestJS
const users = await userRepository.find();
for (const user of users) {
  user.posts = await postRepository.find({ where: { user: { id: user.id } } });
}
This triggers a separate database query for each user to get posts, causing many queries (N+1 problem).
📉 Performance CostTriggers N+1 queries, increasing server response time linearly with number of users.
Performance Comparison
PatternDatabase QueriesQuery CountResponse Time ImpactVerdict
N+1 Query PatternMultiple separate queriesN+1 queriesHigh response time, slower LCP[X] Bad
Eager Loading RelationsSingle joined query1 queryLow response time, faster LCP[OK] Good
ManyToMany without indexesJoin queries on large tables1 queryPotentially slow if unindexed[!] OK
ManyToMany with indexed join tableOptimized join query1 queryFast response, scalable[OK] Good
Rendering Pipeline
Relations affect server-side data fetching before rendering. Efficient queries reduce server response time, improving initial content paint.
→Data Fetching
→Server Response
→Initial Render
⚠️ BottleneckDatabase query time due to inefficient relation loading
Core Web Vital Affected
LCP
This affects database query performance and server response time, impacting how fast data loads and updates in the app.
Optimization Tips
1Avoid N+1 query problem by using eager loading relations.
2Use explicit join tables with indexes for ManyToMany relations.
3Fetch related data in as few queries as possible to reduce server response time.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance problem with fetching related data in a loop without using relations?
AIt reduces the number of queries, speeding up response
BIt causes many database queries, slowing down response time
CIt caches data automatically, improving performance
DIt compresses data to reduce network size
DevTools: Network and Performance panels
How to check: Open DevTools, go to Network tab, filter XHR requests, observe API calls for data fetching. Use Performance tab to record page load and check server response times.
What to look for: Look for multiple API calls fetching related data separately (bad). Single API call with joined data (good). Faster server response times improve LCP.

Practice

(1/5)
1. In NestJS using TypeORM, which decorator correctly defines a OneToMany relationship from an Author entity to a Book entity?
easy
A. @OneToMany(() => Book, book => book.author)
B. @ManyToOne(() => Book, book => book.author)
C. @ManyToMany(() => Book, book => book.author)
D. @OneToOne(() => Book, book => book.author)

Solution

  1. Step 1: Understand the relationship direction

    A OneToMany relationship means one Author has many Books.
  2. Step 2: Identify the correct decorator syntax

    The decorator @OneToMany(() => Book, book => book.author) correctly sets this relation from Author to Book.
  3. Final Answer:

    @OneToMany(() => Book, book => book.author) -> Option A
  4. Quick Check:

    OneToMany from Author to Book = @OneToMany [OK]
Hint: OneToMany decorator links one entity to many others [OK]
Common Mistakes:
  • Confusing OneToMany with ManyToOne
  • Using ManyToMany instead of OneToMany
  • Incorrect arrow function syntax in decorator
2. Which of the following is the correct syntax to define a ManyToOne relation in a NestJS entity?
easy
A. @OneToOne(type => User, user => user.posts)
B. @OneToMany(type => User, user => user.posts)
C. @ManyToOne(type => User, user => user.posts)
D. @ManyToMany(type => User, user => user.posts)

Solution

  1. Step 1: Recognize the relation type

    ManyToOne means many posts belong to one user.
  2. Step 2: Confirm correct decorator syntax

    @ManyToOne(type => User, user => user.posts) is the correct way to define this relation.
  3. Final Answer:

    @ManyToOne(type => User, user => user.posts) -> Option C
  4. Quick Check:

    ManyToOne relation uses @ManyToOne decorator [OK]
Hint: ManyToOne decorator links many items to one parent [OK]
Common Mistakes:
  • Using OneToMany instead of ManyToOne
  • Wrong arrow function parameter name
  • Missing inverse side property
3. Given these entity relations in NestJS with TypeORM:
class Student {
  @ManyToMany(() => Course, course => course.students)
  courses: Course[];
}

class Course {
  @ManyToMany(() => Student, student => student.courses)
  @JoinTable()
  students: Student[];
}

What will be the result of fetching a Course with its students included?
medium
A. A Course object with a single Student object in the 'students' property
B. A Course object with an array of Student objects in the 'students' property
C. A Course object without any students because @JoinTable is missing
D. An error because ManyToMany requires OneToMany on one side

Solution

  1. Step 1: Understand ManyToMany relation with JoinTable

    ManyToMany with @JoinTable on one side creates a join table linking many students to many courses.
  2. Step 2: Fetching Course includes students array

    Fetching a Course with relations loaded returns a Course object with an array of Student objects in 'students'.
  3. Final Answer:

    A Course object with an array of Student objects in the 'students' property -> Option B
  4. Quick Check:

    ManyToMany with @JoinTable returns array of related entities [OK]
Hint: ManyToMany with @JoinTable returns arrays on both sides [OK]
Common Mistakes:
  • Expecting single object instead of array
  • Forgetting @JoinTable on one side
  • Confusing ManyToMany with OneToMany
4. Consider this NestJS entity code snippet:
@Entity()
class Post {
  @OneToMany(() => Comment, comment => comment.post)
  comments: Comment[];
}

@Entity()
class Comment {
  @ManyToOne(() => Post, post => post.comments)
  post: Post;
}

What is wrong if the comments property in Post is not initialized as an array?
medium
A. No issue; undefined is acceptable for relations
B. TypeORM will automatically initialize it as an empty array
C. The database schema will not be created
D. It will cause runtime errors when accessing or pushing comments

Solution

  1. Step 1: Recognize relation property type

    comments is an array of Comment entities, so it should be initialized to avoid undefined.
  2. Step 2: Understand runtime behavior

    If not initialized, accessing or pushing to comments causes runtime errors like 'cannot read property push of undefined'.
  3. Final Answer:

    It will cause runtime errors when accessing or pushing comments -> Option D
  4. Quick Check:

    Uninitialized array relation causes runtime errors [OK]
Hint: Always initialize OneToMany arrays to avoid runtime errors [OK]
Common Mistakes:
  • Assuming TypeORM auto-initializes arrays
  • Ignoring runtime errors from undefined arrays
  • Confusing property initialization with database schema
5. You want to model a social media app where users can follow many other users and be followed by many users. Which NestJS TypeORM relation setup correctly models this ManyToMany self-referencing relation?
hard
A.
@Entity()
class User {
  @ManyToMany(() => User, user => user.followers)
  @JoinTable()
  following: User[];

  @ManyToMany(() => User, user => user.following)
  followers: User[];
}
B.
@Entity()
class User {
  @OneToMany(() => User, user => user.followers)
  following: User[];

  @ManyToOne(() => User, user => user.following)
  followers: User[];
}
C.
@Entity()
class User {
  @ManyToOne(() => User, user => user.followers)
  following: User[];

  @OneToMany(() => User, user => user.following)
  followers: User[];
}
D.
@Entity()
class User {
  @ManyToMany(() => User)
  @JoinTable()
  following: User[];

  @ManyToMany(() => User)
  followers: User[];
}

Solution

  1. Step 1: Understand self-referencing ManyToMany

    Users follow many users and are followed by many users, so a ManyToMany self-relation is needed.
  2. Step 2: Correctly set inverse sides and JoinTable

    @Entity()
    class User {
      @ManyToMany(() => User, user => user.followers)
      @JoinTable()
      following: User[];
    
      @ManyToMany(() => User, user => user.following)
      followers: User[];
    }
    uses @ManyToMany with inverse sides and @JoinTable on one side, correctly modeling the relation.
  3. Final Answer:

    Code snippet with @ManyToMany, inverse sides, and @JoinTable -> Option A
  4. Quick Check:

    Self-referencing ManyToMany needs inverse sides and one @JoinTable [OK]
Hint: Self ManyToMany needs inverse sides and one @JoinTable [OK]
Common Mistakes:
  • Using OneToMany or ManyToOne for many-to-many
  • Missing inverse side property
  • Missing @JoinTable on one side
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard