To connect a Nest.js backend with PostgreSQL for a GraphQL API, you'll generally use TypeORM, which is an ORM that can handle various SQL database interactions in a structured and scalable way. Here’s a step-by-step guide to setting up this connection and integrating it into your GraphQL API.
1. Install Necessary Packages
First, you need to install TypeORM along with pg
, the PostgreSQL driver:
npm install @nestjs/typeorm typeorm pg
2. Configure TypeORM Module
Configure TypeORM in your Nest.js application by modifying the app.module.ts
file to include TypeORM module settings. You need to specify connection settings for your PostgreSQL database.
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'your_username',
password: 'your_password',
database: 'your_database',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true, // Use only in development, remove in production!
}),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: true,
}),
// Your other modules
],
})
export class AppModule {}
3. Create Entity Definitions
Entities in TypeORM are equivalent to tables in your PostgreSQL database. Here’s how you could define an entity for a Recipe
:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import { Field, ObjectType, ID } from '@nestjs/graphql';
@ObjectType()
@Entity()
export class Recipe {
@Field(() => ID)
@PrimaryGeneratedColumn()
id: number;
@Field()
@Column()
title: string;
@Field({ nullable: true })
@Column({ nullable: true })
description?: string;
}
4. Integrate Entity with GraphQL
To integrate this entity with GraphQL, you need to update the resolver to use a service that interacts with the database. First, create a service:
nest generate service recipe
Now, implement the service:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Recipe } from './recipe.entity';
import { CreateRecipeInput, UpdateRecipeInput } from './dto/recipe.input';
@Injectable()
export class RecipeService {
constructor(
@InjectRepository(Recipe)
private recipeRepository: Repository<Recipe>,
) {}
findAll(): Promise<Recipe[]> {
return this.recipeRepository.find();
}
findOne(id: number): Promise<Recipe> {
return this.recipeRepository.findOneBy({ id });
}
create(createRecipeInput: CreateRecipeInput): Promise<Recipe> {
const newRecipe = this.recipeRepository.create(createRecipeInput);
return this.recipeRepository.save(newRecipe);
}
async update(id: number, updateRecipeInput: UpdateRecipeInput): Promise<Recipe> {
const recipe = await this.recipeRepository.preload({
id: id,
...updateRecipeInput,
});
if (!recipe) {
throw new Error('Recipe not found');
}
return this.recipeRepository.save(recipe);
}
async remove(id: number): Promise<void> {
await this.recipeRepository.delete(id);
}
}
5. Update Resolver to Use Service
Finally, modify your resolver to use the service for handling database operations:
import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { Recipe } from './entities/recipe.entity';
import { RecipeService } from './recipe.service';
import { CreateRecipeInput, UpdateRecipeInput } from './dto/recipe.input';
@Resolver(() => Recipe)
export class RecipeResolver {
constructor(private readonly recipeService: RecipeService) {}
@Query(() => [Recipe])
recipes() {
return this.recipeService.findAll();
}
@Query(() => Recipe, { nullable: true })
recipe(@Args('id', { type: () => ID }) id: number) {
return this.recipeService.findOne(id);
}
@Mutation(() => Recipe)
createRecipe(@Args('createRecipeData') createRecipeData: CreateRecipeInput) {
return this.recipeService.create(createRecipeData);
}
@Mutation(() => Recipe)
updateRecipe(@Args('id') id: number, @Args('updateRecipeData') updateRecipeData: UpdateRecipeInput) {
return this.recipeService.update(id, updateRecipeData);
}
@Mutation(() => Boolean)
deleteRecipe
(@Args('id', { type: () => ID }) id: number) {
return this.recipeService.remove(id).then(() => true);
}
}
This setup provides a robust structure for handling CRUD operations in your GraphQL API, leveraging the power of TypeORM for database interactions with PostgreSQL.
Support My Work ❤️
If you enjoy my content and find it valuable, consider supporting me by buying me a coffee. Your support helps me continue creating and sharing useful resources. Thank you!
Connect with Me 🌍
Let’s stay connected! You can follow me or reach out on these platforms:
🔹 YouTube – Tutorials, insights & tech content
🔹 LinkedIn – Professional updates & networking
🔹 GitHub – My open-source projects & contributions
🔹 Instagram – Behind-the-scenes & personal updates
🔹 X (formerly Twitter) – Quick thoughts & tech discussions
I’d love to hear from you—whether it’s feedback, collaboration ideas, or just a friendly hello!
Disclaimer
This content has been generated with the assistance of AI. While I strive for accuracy and quality, please verify critical information independently.
Top comments (0)