mavzermete 1
mavzermete
kaptanmikro1 1
kaptanmikro1
Jack.Wrestler 1
Jack.Wrestler
TuZaKK 1
TuZaKK
noisiv 1
noisiv
Manwe Work 1
Manwe Work
Agora Metin2 1
Agora Metin2
EnesDeniz™ 1
EnesDeniz™
Cancan.1234 1
Cancan.1234
lHezarfeNl 1
lHezarfeNl
Bodyguardd 1
Bodyguardd
kralhakan2009 1
kralhakan2009
Reklam vermek için turkmmo@gmail.com

NestJS + Prisma + PostgreSQL ile REST API

  • Konuyu başlatan Konuyu başlatan VictoryasHD
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 2
  • Görüntüleme Görüntüleme 13

1792515264650.png

​

NestJS + Prisma + PostgreSQL ile REST API Geliştirmek: CRUD, Doğrulama ve Swagger​

REST API geliştirirken kodun yalnızca çalışması değil, büyüdükçe sürdürülebilir kalması da önemlidir. Controller, servis, veritabanı erişimi ve doğrulama işlemlerinin belirli bir düzen içerisinde tutulması, özellikle ekip çalışmalarında büyük avantaj sağlar.

Bu yazıda NestJS, Prisma ORM ve PostgreSQL kullanarak basit bir blog API'si oluşturacağız. Blog yazıları için CRUD endpoint'leri hazırlayacak ve Swagger üzerinden API dokümantasyonu sunacağız.

1. Teknolojilere genel bakış​

NestJS: Node.js üzerinde modüler ve düzenli backend uygulamaları geliştirmeye yardımcı olan bir framework'tür.

Prisma ORM: Veritabanı şemasından tip güvenli bir istemci üretir ve veritabanı işlemlerini kolaylaştırır.

PostgreSQL: İlişkisel verileri saklamak için kullanılır.

Swagger / OpenAPI: API endpoint'lerini, parametrelerini ve yanıtlarını dokümante eder.

Bu bileşenleri birlikte kullanarak hem geliştiriciler hem de API tüketicileri için daha anlaşılır bir yapı oluşturabiliriz.

2. NestJS projesi oluşturmak​

NestJS CLI kurulumuyla başlayalım:

npm install -g @nestjs/cli
nest new blog-api
cd blog-api
Prisma'yı projeye eklemek için:

npm install prisma @prisma/client
npx prisma init
Bu yazıdaki Prisma yapılandırması, Prisma 7 ve NestJS 11 için güncellenmiş kaynak yaklaşımını esas alır. Prisma 7'de veritabanı bağlantısı ve istemci üretimiyle ilgili yapılandırmalar eski sürümlere göre farklılık gösterebilir.

3. PostgreSQL bağlantısı​

PostgreSQL üzerinde blog_api isimli bir veritabanı oluşturduğumuzu varsayalım.

.env dosyasına bağlantı adresini ekleyelim:

DATABASE_URL="postgresql://postgres:password@localhost:5432/blog_api"
Gerçek kullanıcı bilgileri kullanılmalı ve bu dosya kaynak kod deposuna gönderilmemelidir.

Prisma 7 projelerinde bağlantı yapılandırması ayrıca prisma.config.ts üzerinden yönetilir. Örneğin:

import "dotenv/config";
import { defineConfig, env } from "prisma/config";

export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
Prisma 7'nin veritabanı sürücüsü yaklaşımı nedeniyle PostgreSQL için uygun driver adapter kurulmalı ve Prisma Client bu yapılandırmaya göre oluşturulmalıdır.

4. Blog modeli oluşturmak​

prisma/schema.prisma dosyasında blog yazısı modelini tanımlayalım:

generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}

datasource db {
provider = "postgresql"
}

model Post {
id Int @id @default(autoincrement())
title String
content String
published Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
Burada:

  • id, her yazı için benzersiz bir kimlik oluşturur.
  • title, yazı başlığını tutar.
  • content, yazının içeriğini saklar.
  • published, yazının yayın durumunu belirtir.
  • createdAt ve updatedAt, kayıt zamanlarını yönetir.
Bu model basit bir başlangıçtır. Gerçek bir blog uygulamasında kullanıcılar, kategoriler, etiketler ve yorumlar için ilişkiler eklenebilir.

Prisma 7'de prisma-client generator'ı için belirtilen çıktı dizini önemlidir. Servis katmanında import yolu, projede üretilen gerçek dosya yapısıyla eşleşmelidir.

5. Migration ve Prisma Client​

Şema değişikliklerini veritabanına uygulamak için:

npx prisma migrate dev --name init
npx prisma generate
İlk komut migration oluşturup geliştirme veritabanına uygular. İkinci komut Prisma Client'ı üretir.

Üretim ortamında migration uygulamak için genellikle şu komut kullanılır:

npx prisma migrate deploy
Geliştirme ve üretim migration süreçleri birbirinden ayrılmalıdır. Üretimde migrate dev kullanılmamalı, migration dosyaları sürüm kontrolünde tutulmalıdır.

6. Prisma servisi oluşturmak​

NestJS içinde veritabanı erişimini ayrı bir servis üzerinden yönetmek düzenli bir mimari sağlar.

Prisma 7 için uygun PostgreSQL driver adapter kurulmuş ve PrismaClient doğru bağlantı yapılandırmasıyla oluşturulmuş olmalıdır.

Örneğin servis katmanında temel yaklaşım şu şekildedir:

import { Injectable, OnModuleDestroy } from "@nestjs/common";
import { PrismaClient } from "./generated/prisma/client";

@Injectable()
export class PrismaService
extends PrismaClient
implements OnModuleDestroy
{
async onModuleDestroy() {
await this.$disconnect();
}
}
Bu örnekte PrismaClient import yolu, generator çıktısına göre düzenlenmelidir. Prisma 7 projelerinde uygun driver adapter'ın istemci oluşturulurken yapılandırılması gerekir; bağlantı kurulumu eksik bırakılmamalıdır.

PrismaService daha sonra NestJS modüllerine provider olarak eklenebilir.

7. DTO ve veri doğrulama​

API'ye gelen verilerin doğrulanması için DTO kullanabiliriz.

Öncelikle gerekli paketleri yükleyelim:

npm install class-validator class-transformer
create-post.dto.ts:

import {
IsBoolean,
IsNotEmpty,
IsOptional,
IsString,
MaxLength,
} from "class-validator";

export class CreatePostDto {
@IsString()
@IsNotEmpty()
@MaxLength(200)
title!: string;

@IsString()
@IsNotEmpty()
content!: string;

@IsOptional()
@IsBoolean()
published?: boolean;
}
Daha sonra main.ts dosyasında global doğrulama katmanını etkinleştirelim:

import { ValidationPipe } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
const app = await NestFactory.create(AppModule);

app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
}),
);

await app.listen(process.env.PORT ?? 3000);
}

bootstrap();
Bu yapı, DTO'da tanımlanmamış alanların reddedilmesine ve geçersiz isteklerin controller'a ulaşmadan doğrulanmasına yardımcı olur.

8. CRUD servis işlemleri​

Blog yazıları için dört temel işlem gerekir:

  • Create: Yeni yazı oluşturma
  • Read: Yazıları veya tek bir yazıyı getirme
  • Update: Yazıyı güncelleme
  • Delete: Yazıyı silme
posts.service.ts içerisinde temel işlemler şöyle modellenebilir:

import {
Injectable,
NotFoundException,
} from "@nestjs/common";
import { PrismaService } from "../prisma/prisma.service";
import { CreatePostDto } from "./dto/create-post.dto";

@Injectable()
export class PostsService {
constructor(private readonly prisma: PrismaService) {}

create(data: CreatePostDto) {
return this.prisma.post.create({
data,
});
}

findAll() {
return this.prisma.post.findMany({
orderBy: {
createdAt: "desc",
},
});
}

async findOne(id: number) {
const post = await this.prisma.post.findUnique({
where: { id },
});

if (!post) {
throw new NotFoundException("Yazı bulunamadı.");
}

return post;
}

async update(id: number, data: Partial<CreatePostDto>) {
await this.findOne(id);

return this.prisma.post.update({
where: { id },
data,
});
}

async remove(id: number) {
await this.findOne(id);

return this.prisma.post.delete({
where: { id },
});
}
}
Bu servis örneği, CRUD işlemlerinin mantığını gösterir. Gerçek uygulamada güncelleme DTO'su ayrı tanımlanmalı, kullanıcı yetkileri kontrol edilmeli ve Prisma hataları uygun HTTP hata yanıtlarına dönüştürülmelidir.

9. Controller ve REST endpoint'leri​

Controller, HTTP isteklerini karşılar ve servis katmanına yönlendirir.

posts.controller.ts:

import {
Body,
Controller,
Delete,
Get,
Param,
ParseIntPipe,
Patch,
Post,
} from "@nestjs/common";

import { PostsService } from "./posts.service";
import { CreatePostDto } from "./dto/create-post.dto";

@Controller("posts")
export class PostsController {
constructor(
private readonly postsService: PostsService,
) {}

@Post()
create(@Body() body: CreatePostDto) {
return this.postsService.create(body);
}

@Get()
findAll() {
return this.postsService.findAll();
}

@Get(":id")
findOne(
@Param("id", ParseIntPipe) id: number,
) {
return this.postsService.findOne(id);
}

@Patch(":id")
update(
@Param("id", ParseIntPipe) id: number,
@Body() body: Partial<CreatePostDto>,
) {
return this.postsService.update(id, body);
}

@Delete(":id")
remove(
@Param("id", ParseIntPipe) id: number,
) {
return this.postsService.remove(id);
}
}
Bu controller aşağıdaki endpoint'leri sağlar:

HTTPEndpointİşlem
POST/postsYeni yazı oluşturur
GET/postsYazıları listeler
GET/posts/:idTek yazıyı getirir
PATCH/posts/:idYazıyı günceller
DELETE/posts/:idYazıyı siler
Örneğin GET /posts/1 isteği, kimliği 1 olan yazıyı getirir. Kayıt bulunamazsa servis 404 Not Found hatası döndürür.

10. Swagger ile API dokümantasyonu​

Swagger, API endpoint'lerini görsel bir arayüz üzerinden incelemeyi ve test etmeyi kolaylaştırır.

Gerekli paketi yükleyelim:

npm install @nestjs/swagger
main.ts dosyasına Swagger yapılandırmasını ekleyebiliriz:

import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";

// bootstrap() içinde, app oluşturulduktan sonra:

const config = new DocumentBuilder()
.setTitle("Blog API")
.setDescription("Blog yazılarını yönetmek için REST API")
.setVersion("1.0.0")
.build();

const document = SwaggerModule.createDocument(app, config);

SwaggerModule.setup("api-docs", app, document);
Uygulama çalıştığında:


adresinden Swagger arayüzüne erişilebilir.

Bu örnekte Swagger kurulumu gösterilmiştir. Endpoint'lerin dokümantasyonda daha ayrıntılı görünmesi için @ApiTags, @ApiOperation, @ApiResponse ve DTO'larda uygun Swagger dekoratörleri de kullanılmalıdır.

11. Production ortamında dikkat edilmesi gerekenler​

  • Kimlik doğrulama ve rol tabanlı yetkilendirme ekleyin.
  • Sayfalama, filtreleme ve sıralama desteği sağlayın.
  • Güncelleme DTO'sunu oluşturma DTO'sundan ayırın.
  • Hata mesajlarını merkezi olarak yönetin.
  • Prisma Client ve PostgreSQL bağlantılarını doğru yapılandırın.
  • Migration'ları kontrollü bir deployment sürecine dahil edin.
  • API endpoint'lerini otomatik testlerle doğrulayın.
  • Üretim ortamında loglama, izleme ve yedekleme süreçlerini planlayın.
Özellikle bir blog yazısını silmek veya yayın durumunu değiştirmek gibi işlemler, yalnızca yetkili kullanıcıların erişebileceği şekilde korunmalıdır.

Sonuç​

NestJS, Prisma ORM ve PostgreSQL birlikte kullanıldığında modüler, tip güvenli ve sürdürülebilir bir REST API geliştirmek mümkündür.

NestJS'in controller ve servis yapısı uygulama mantığını düzenlerken Prisma veritabanı işlemlerini kolaylaştırır. Swagger ise API'nin hem ekip içerisinde hem de harici istemciler tarafından anlaşılmasını sağlar.

Bu yazıdaki örnekler temel bir blog API'sinin iskeletini oluşturur. Üretim ortamına geçmeden önce sürüm uyumluluğu, veritabanı bağlantısı, yetkilendirme, hata yönetimi ve test süreçleri tamamlanmalıdır.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst