Nest.js ile GraphQL API Nasıl Oluşturulur?

Bu makalede, NestJS ile temiz mimarisinden ve tip güvenliğinden yararlanarak nasıl GraphQL API oluşturacağınızı öğreneceksiniz.

NestJS, kullanıcıların tip güvenliği ve katı bir mimari model sağlayarak ölçeklenebilir kurumsal düzeyde arka uç uygulamaları oluşturmalarına yardımcı olan bir NodeJS çerçevesidir.

GraphQL, sorgulara tam olarak talep ettikleri verilerle yanıt vererek elde ettiği hız ve kararlılık nedeniyle REST’e alternatif olarak yaygın şekilde kullanılan uygulama programlama arayüzleri (API’ler) için bir sorgu dilidir. Bu GraphQL özelliği, REST tarafından ortaya çıkarılan aşırı getirme ve yetersiz getirme sorununu çözer.

Geliştirme Ortamınızı Kurma

Nest.js CLI sisteminizde genel olarak yüklü değilse, yüklemek için aşağıdaki komutu çalıştırın:

npm i -g @nestjs/cli

Nest.js CLI, geliştirme sürecinizi kolaylaştırmak için şablon kod oluşturmanıza yardımcı olan çeşitli komutlar içerir.

Ardından, aşağıdaki komutu çalıştırarak projeyi oluşturun ve gerekli başlangıç dosyalarını oluşturun:

nest new graphql-api

Ardından, proje dizininize cd ile girmek için aşağıdaki komutu çalıştırın:

cd graphql-api

Ardından, aşağıdaki komutu çalıştırarak gerekli bağımlılıkları yükleyin:

npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-express

Yukarıda yüklenen bağımlılıklar şunları içerir:

  • nest/graphql
  • nestjs/apollo
  • graphql
  • apollo-server-express

Ardından, aşağıdaki komutu çalıştırarak TypeORM paketini ve sqlite veritabanı sürücüsünü yükleyin:

npm install @nestjs/typeorm typeorm sqlite3

Bir veritabanına bağlanmak, okumak ve yazmak için yukarıda yüklenen paketlere ihtiyacınız olacaktır.

Nest.js’de GraphQL’i Yapılandırma

Nest.js bir GraphQL API oluşturmanın iki yolunu sunar: kod öncelikli ve şema öncelikli yaklaşımlar.

Kod öncelikli yaklaşım, ilgili GraphQL şemasını oluşturmak için TypeScript dekoratörlerinin ve sınıflarının kullanımını içerir.

Şema öncelikli yaklaşım GraphQL Şema Tanım Dili (SDL) dosyalarının kullanımını içerirken, Nest.js GraphQL Şemasına dayalı sınıfları veya arayüzleri kullanarak TypeScript tanımları oluşturur.

Bu eğitimde, farklı diller arasında bağlam geçişini önlemek için kod öncelikli yaklaşımın kullanımı ele alınacaktır.

Önce kod yaklaşımını kullanmak için uygulamanızın giriş dosyası olan app.module.ts dosyasına gidin ve @nestjs/graphql adresinden GraphQLModule öğesini içe aktarın. Bunun gibi:

import { GraphQLModule } from '@nestjs/graphql';

Ardından, imports dizinizde GraphQLModule‘ün forRoot yöntemini çağırın. Bu yöntem argüman olarak bir yapılandırma nesnesi alır. Yapılandırma seçenekleri temel GraphQL sürücüsünden geçirilir (Bu eğitimde Apollo sürücüsü kullanılmaktadır). Yapılandırma nesnesindeki autoSchemaFile özelliğini schema.gql olarak ayarlayın. Bunun gibi:

//app.module.ts
GraphQLModule.forRoot({ autoSchemaFile: 'schema.gql' }),

autoSchemaFile özelliği, otomatik olarak oluşturulan şemanızın saklanacağı dosya yoludur.

Bir Veritabanına Bağlanma

Uygulamanızı bir veritabanına bağlamak için app.module.ts dosyanıza gidin ve @nestjs/typeorm adresinden TypeOrmModule öğesini içe aktarın.

Bu şekilde:

import { TypeOrmModule } from '@nestjs/typeorm';

Ardından, aşağıdaki kod bloğunu imports dizinize ekleyin:

TypeOrmModule.forRoot({
      type: 'sqlite',
      database: ':memory:',
      entities: ['dist/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),

Yukarıdaki kod bloğu, uygulamanız ile bir Sqlite veritabanı arasında bir veritabanı bağlantısı oluşturur ve bağlantıyı uygulamanızdaki tüm modüller arasında paylaştırır.

Kaynak Oluşturma

Ardından, aşağıdaki komutu çalıştırarak kodunuzu düzenlemek için bir modül oluşturun:

nest g module blog

Yukarıdaki komut uygulamanız için bir blog modülü oluşturur.

Ardından, bir hizmet oluşturmak için aşağıdaki komutu çalıştırın:

nest g service blog

Yukarıdaki kod bloğu uygulamanızda bir hizmet oluşturur ve kaydeder. Bu servis, uygulamanız için tüm iş mantığını içerecek ve işleyecektir.

Ardından, bir çözümleyici oluşturmak için aşağıdaki komutu çalıştırın:

nest g resolver

Yukarıdaki kod bloğu uygulamanızda bir çözümleyici oluşturur ve kaydeder. Çözümleyici, GraphQL sorgularını ve mutasyonlarını veriye dönüştürmek için talimatları belirtir ve bir şemada belirtilen veri şeklini eşzamanlı veya eşzamansız olarak döndürür.

Bir Varlık Oluşturma

Varlık, verilerin bir veritabanında nasıl depolandığını belirten bir alanlar koleksiyonudur.

Bir Entity oluşturmak için, modül klasörünüzde (blog), .entity.ts kuralını izleyerek bir entity dosyası oluşturun, örneğin, blog.entity.ts.

Varlık dosyanızda Sütun, Varlık ve PrimaryGeneratedColumn öğelerini typeorm‘dan içe aktarın. Bunun gibi:

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

Column dekoratörü, bir veritabanına sütun olarak eklediği alanları ekler. Entity dekoratörü, ek açıklama eklediği sınıfı bir varlık olarak işaretler. PrimaryGeneratedColumn dekoratörü, tablonuz için benzersiz tanımlayıcı olarak eklediği özelliği işaretler ve otomatik olarak oluşturur.

Ardından, Blog adında bir sınıf oluşturun ve dışa aktarın. Ardından, sınıfı bir varlık olarak işaretlemek için Entity dekoratörü ile açıklama ekleyin. Bunun gibi:

@Entity()
export class Blog {}

Bu eğitim bir blog API’si içerdiğinden, sınıfınıza bir id, title, body, author ve date özelliği ekleyin. Ardından, id özelliği hariç her bir özelliğe Column dekoratörü ile açıklama ekleyin. id özelliğine PrimaryGeneratedColumn dekoratörü ile açıklama ekleyin.

Bu şekilde:

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Blog {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  body: string;

  @Column()
  author: string;

  @Column()
  date: string;
}

Nesne Türü Oluşturma

Nesne türü, istemcinin etkileşime girmesi gereken nesneyi temsil eden bir GraphQL şema tanımıdır. Örneğin, bir blog API’si oluşturuyorsanız, blog şemasını/varlığını bir TypeScript sınıfı ile tanımlamanız ve her alana uygun dekoratörlerle açıklama eklemeniz gerekir.

Ardından, entity dosyanızda Int türünü ve Field ve ObjectType dekoratörlerini @nestjs/graphql adresinden içe aktarın. Bunun gibi:

import { Field, Int, ObjectType } from '@nestjs/graphql';

Alan dekoratörü, belirli bir sınıf özelliğini GraphQL alanı olarak işaretler. Şemada yalnızca bu dekoratörle işaretlenmiş özellikler tanımlanacaktır. Argüman olarak isteğe bağlı bir dönüş tipi fonksiyonu ve bir yapılandırma nesnesi kabul eder.

Int türü, TypeScript ve GraphQL tür sistemleri arasındaki olası belirsizliği gidermek için gereklidir. Tamsayı veya float olabildikleri için yalnızca sayı değerlerine sahip özellikler için gereklidir.

ObjectType dekoratörü bir sınıfı GraphQL türü olarak işaretler.

Ardından, Blog sınıfınızı GraphQL türü olarak işaretlemek için ObjectType dekoratörü ile açıklama ekleyin. Bunun gibi:

@ObjectType()
export class Blog {}

Son olarak, türünüzün gerekli özelliklerini sınıf içinde belirtin ve her birine Field dekoratörü ile açıklama ekleyin. Örneğin:

//blog.entity.ts
import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
@ObjectType()
export class Blog {
  @PrimaryGeneratedColumn()
  @Field((type) => Int)
  id: number;

  @Column()
  @Field()
  title: string;

  @Column()
  @Field()
  body: string;

  @Column()
  @Field()
  author: string;

  @Column()
  @Field()
  date: string;
}

Tamamlanmış Nesne Türünüz yukarıdaki kod bloğuna benzemelidir.

Yukarıdaki kod bloğunda sayı türüne sahip id' nin, TypeScript ve GraphQL tür sistemleri arasındaki belirsizliği önlemek için açıkça bir tamsayı olarak belirtildiğine dikkat edin.

Son olarak, uygulamanız ile veritabanınız arasında bir erişim katmanı oluşturmak için Entity’nizi uygulamanıza enjekte edin.

Bunu başarmak için blog.module.ts dosyanıza gidin, @nestjs/typeorm adresinden TypeOrmModule öğesini içe aktarın ve Blog varlığınızı içe aktarın.

Ardından, aşağıdaki kod bloğunu modül dekoratörünüze ekleyin:

imports: [TypeOrmModule.forFeature([Blog])],

Yukarıdaki kod bloğu, uygulamanız ile veritabanı arasında bir erişim katmanı görevi görecek bir depo oluşturur.

Hizmet Oluşturma

Daha önce oluşturduğunuz blog.service.ts hizmet dosyasına gidin ve @nestjs/typeorm adresinden InjectRepository dosyasını ve nesne türünüzü içe aktarın.

Bu şekilde:

import { InjectRepository } from '@nestjs/typeorm';
import { Blog } from './blog.entity';

Ardından, deponuzu enjekte etmek için aşağıdaki kod bloğunu BlogService sınıfınıza ekleyin:

constructor(
    @InjectRepository(Blog)
    private blogRepository: Repository<Blog>,
  ) {}

Ardından, veritabanındaki tüm blogları alma mantığını uygulamak için aşağıdaki kod bloğunu hizmet sınıfınıza ekleyin:

async getAll(): Promise<Blog[]> {
    return await this.blogRepository.find();
  }

Daha sonra, veritabanınıza yeni bir blog ekleme mantığını uygulamanız gerekecek, ancak önce bir Girdi Türü oluşturmanız gerekecek.

Girdi Türü Oluşturma

Mutasyonlarınız için karmaşık nesneler alan bir girdi türü oluşturmak için blog klasörünüzde bir dtos klasörü oluşturun. Ardından, dtos klasörünüzde create-blog.input.ts adında yeni bir dosya oluşturun.

create-blog.input.ts dosyanızda Field ve InputType dekoratörlerini içe aktarın. Bunun gibi:

import { Field, InputType } from '@nestjs/graphql';

InputType dekoratörü bir sınıfı GraphQL giriş türü olarak işaretler.

Ardından, BlogInput adında bir sınıf oluşturun ve dışa aktarın. Ardından, sınıfa InputType dekoratörü ile açıklama ekleyin. Bunun gibi:

@InputType()
export class BlogInput {}

Son olarak, gerekli tüm blog özelliklerini ekleyin ve bunlara Field dekoratörü ile açıklama ekleyin.

Bu şekilde:

//create-blog.input.ts
import { Field, InputType } from '@nestjs/graphql';

@InputType()
export class BlogInput {
  @Field()
  id: number;

  @Field()
  title: string;

  @Field()
  body: string;

  @Field()
  author: string;

  @Field()
  date: string;
}

Tamamlanan giriş türünüz yukarıdaki kod bloğuna benzemelidir.

Ardından, giriş türünüzü hizmet dosyanıza aktarın ve veritabanına bir blog ekleme mantığını uygulamak için aşağıdaki kod bloğunu hizmet sınıfınıza ekleyin:

async createBlog(blogInput: BlogInput): Promise<Blog> {
    const newBlog = this.blogRepository.create(blogInput);

    return this.blogRepository.save(newBlog);
  }

Girdi türü, gelen veriler için bir doğrulama mekanizması olarak normal bir Nest.js veri aktarım nesnesinin uygulandığı şekilde uygulanır. dtos gibi, class-validator paketini kullanarak veriler üzerinde ek doğrulama da gerçekleştirebilirsiniz.

Çözümleyici Oluşturma

Daha önce oluşturduğunuz Resolver dosyasına ( blog.resolver.ts) gidin ve varlığınızı, girdi türünüzü ve hizmetinizi içe aktarın. Bunun gibi:

import { Blog } from './blog.entity';
import { BlogService } from './blog.service';
import { BlogInput } from './dto/create-blog.input';

Ardından, hizmetinizi çözümleyicinize enjekte etmek için aşağıdaki kod bloğunu Resolver sınıfınıza ekleyin:

constructor(private blogService: BlogService) {}

Ardından, @nestjs/graphql‘den Args, Mutation ve Query dekoratörlerini içe aktarın.

Bu şekilde:

import { Args, Mutation, Query } from '@nestjs/graphql';

Args dekoratörü, temel platformdan argüman nesnesini çıkarır ve dekore edilmiş parametreyi tüm argümanların veya belirtilen tek bir argümanın değeriyle doldurur.

Mutasyon dekoratörü bir rotayı mutasyon olarak belirtir.

Sorgu dekoratörü bir rotayı sorgu olarak belirtir.

Ardından, nesne türünü belirtmek için aşağıdaki işlevi Resolver dekoratörüne aktarın:

(of) => Blog

Ardından, getAll yöntemini çözümlemek için aşağıdaki kod bloğunu Resolver sınıfınıza ekleyin.

 @Query((type) => [Blog])
  async getAllBlogs() {
    return this.blogService.getAll();
  }

Son olarak, createBlog yöntemini çözümlemek için aşağıdaki kod bloğunu Resolver sınıfınıza ekleyin.

 @Mutation((returns) => Blog)
  createBlog(@Args('blogInput') blogInput: BlogInput): Promise<Blog> {
    return this.blogService.createBlog(blogInput);
  }

Not: Her dekoratör için dönüş tipi fonksiyonunu belirttiğinizden emin olun.

Tamamlanmış Resolver sınıfınız aşağıdaki kod bloğu gibi görünmelidir:

@Resolver((of) => Blog)
export class BlogResolver {
  constructor(private blogService: BlogService) {}

  @Query((type) => [Blog])
  async getAllBlogs() {
    return this.blogService.getAll();
  }

  @Mutation((returns) => Blog)
  createBlog(@Args('blogInput') blogInput: BlogInput): Promise<Blog> {
    return this.blogService.createBlog(blogInput);
  }
}

GraphQL Playground kullanarak API’nizi test etme

Uygulamanızı varsayılan olarak mevcut olan GraphQL oyun alanını kullanarak test etmek için aşağıdaki komutu çalıştırın ve http://localhost:3000/graphql adresine gidin.

npm start

Ardından, aşağıdaki resimde gösterildiği gibi sorgularınızı ve mutasyonlarınızı test edebileceğiniz bir oyun alanı görmelisiniz.

GraphQL oyun alanı

Veritabanından tüm blogları almak için aşağıdaki sorguyu çalıştırın:

query getAll{
  getAllBlogs {
    id,
    title,
    body,
    author,
    date
  }
}

Aşağıdaki resimde bir örnek gösterilmektedir:

Veritabanınıza bir blog eklemek için aşağıdaki mutasyonu çalıştırın:

mutation createBlog {
  createBlog (blogInput: {
    id: 1, 
    title: "GraphQL is great", 
    body: "GraphQL APIs are faster than REST APIs", 
    author: "David Ekete",
    date: "01-02-03"
  }) {
    id,
    title,
    body,
    author,
    date,
  }
}

Aşağıdaki resimde bir örnek gösterilmektedir:

GraphQL oyun alanı

Back4app ve GraphQL

Veri getirme kontrolü gibi GraphQL’in REST’e göre sahip olduğu birçok avantaj nedeniyle Back4app platformu, platformda çalışan ayrıştırma uygulamalarınıza entegre edilmiş bir GraphQL API sağlar.

Bu entegrasyon, basit GraphQL sorguları ve mutasyonları yazarak sunucunuzun arka uç sağlığını kontrol etmenize, veritabanınızda Oluşturma, Okuma, Güncelleme, Silme (CRUD) işlemleri gerçekleştirmenize ve çok daha fazlasını yapmanıza olanak tanır.

Örneğin, GraphQL API kullanarak arka uç sunucunuzun durumunu kontrol etmek için aşağıdaki sorguyu çalıştırın:

query Health {
  health
}

Yukarıdaki sorgu geri dönecektir:

{
  "data": {
    "health": true
  }
}

GraphQL özelliğini kullanmaya başlamak için Parse kontrol panelinize gidin ve uygulamanızı seçip tıklayın. Uygulamanızın kullanıcı arayüzünde Core’u seçip tıklayın, ardından API console’u seçip tıklayın ve GraphQL console’u seçin.

Yukarıdaki talimatları izlediğinizde, geliştirme sırasında kullandığınız GraphQL oyun alanına benzer şekilde sorgularınızı ve mutasyonlarınızı çalıştırabileceğiniz bir GraphQL konsolu açılacaktır. Back4app’in GraphQL özelliği hakkında daha fazla bilgiyi Back4app dokümantasyonunda bulabilirsiniz.

Sonuç

Bu makale, Nest.js’de nasıl GraphQL API oluşturabileceğinizi ve GraphQL oyun alanı ile API’yi nasıl test edebileceğinizi ele aldı. GraphQL API’lerinin REST API’lerine göre çeşitli avantajları vardır.

Ancak, her uygulama için ideal değildirler. Uygulamanız için hangisinin uygun olacağını seçmeden önce GraphQL ve REST’in artılarını ve eksilerini göz önünde bulundurduğunuzdan emin olun.

GraphQL veya REST seçiminiz ne olursa olsun, uygulamanızı yine de dağıtmanız gerekir. Back4app, yeniden kullanılabilir şablonlar kullanarak tekrar eden görevleri ortadan kaldırarak ve arka uç altyapınızın çoğunu yöneterek arka uç oluşturma sürecinizi basitleştiren, açık kaynak teknolojilerine dayalı düşük kodlu bir BaaS’tır.

Back4app’in özelliklerinden bazıları gerçek zamanlı bir veritabanı, bulut işlevleri, yerel API’ler ve SDK’lar, eksiksiz bir kullanıcı yönetim sistemi ve çok daha fazlasını içerir.

Bu platform ayrıca, platformu ücret ödemeden keşfetmenize olanak tanıyan ücretsiz bir katmana sahiptir.

Mutlu inşaatlar!

SSS

GraphQL Nedir?

GraphQL, Facebook tarafından 2012 yılında oluşturulan API’ler için açık kaynaklı bir veri sorgulama ve işleme dilidir.

Nest.JS Nedir?

Nest.JS, verimli, ölçeklenebilir sunucu tarafı uygulamaları oluşturmak için açık kaynaklı bir Node.js çerçevesidir.

Nest.JS ile GraphQL API nasıl oluşturulur?

– Nest.js’de GraphQL’i yapılandırın
– Bir Veritabanına Bağlanın
– Kaynaklar Oluşturun
– Bir varlık oluşturun
– Bir nesne türü oluşturun
– Bir hizmet oluşturun


Leave a reply

Your email address will not be published.