Apollo + GraphQL — NestJS da ishlash
Muammodan boshlaylik
Oldingi darsda GraphQL nima ekanini bildik. Endi NestJS da qanday yozilishini ko'ramiz.
NestJS da code-first yondashuvi ishlatiladi: TypeScript yozasiz, GraphQL schema avtomatik yaratiladi. Avval sxema yozib, keyin resolver emas — aksincha.
O'rnatish
npm install @nestjs/graphql @nestjs/apollo @apollo/server graphql
Fayl tuzilmasi
src/
users/
dto/
create-user.input.ts ← mutation uchun kiritma
user.model.ts ← GraphQL tipi (@ObjectType)
users.resolver.ts ← so'rovlarni bajaruvchi
users.service.ts ← biznes logika
users.module.ts
app.module.ts ← GraphQLModule shu yerda sozlanadi
AppModule ga ulash
// app.module.ts
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'), // ← schema avtomatik yaratiladi
playground: true, // ← brauzerda sinab ko'rish uchun
}),
UsersModule,
],
})
export class AppModule {}
ObjectType — GraphQL tipi
TypeScript klassidan GraphQL tipi yaratamiz:
// users/user.model.ts
import { ObjectType, Field, Int } from '@nestjs/graphql';
@ObjectType() // ← bu klass GraphQL tipiga aylanadi
export class User {
@Field(() => Int) // ← Int tip
id: number;
@Field() // ← String tip (avtomatik)
name: string;
@Field()
email: string;
}
NestJS bu klassdan schema avtomatik yaratadi:
type User {
id: Int!
name: String!
email: String!
}
Resolver — so'rovlarni bajarish
Controller ga o'xshaydi, lekin HTTP o'rniga GraphQL so'rovlarini bajaradi:
// users/users.resolver.ts
import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { User } from './user.model';
import { UsersService } from './users.service';
import { CreateUserInput } from './dto/create-user.input';
@Resolver(() => User)
export class UsersResolver {
constructor(private usersService: UsersService) {}
// query { users { id name } }
@Query(() => [User])
users() {
return this.usersService.findAll();
}
// query { user(id: 1) { name } }
@Query(() => User, { nullable: true })
user(@Args('id', { type: () => Int }) id: number) {
return this.usersService.findOne(id);
}
// mutation { createUser(input: {...}) { id } }
@Mutation(() => User)
createUser(@Args('input') input: CreateUserInput) {
return this.usersService.create(input);
}
}
InputType — mutation uchun
Ko'p argument o'rniga bitta ob'ekt:
// users/dto/create-user.input.ts
import { InputType, Field } from '@nestjs/graphql';
@InputType()
export class CreateUserInput {
@Field()
name: string;
@Field()
email: string;
}
Frontend dan yuborish:
mutation {
createUser(input: { name: "Ali", email: "ali@test.com" }) {
id
name
}
}
Module
// users/users.module.ts
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service';
@Module({
providers: [UsersResolver, UsersService],
})
export class UsersModule {}
Playground da sinash
http://localhost:3000/graphql ga kiring:
# Barcha userlar
query {
users {
id
name
email
}
}
# Bitta user
query {
user(id: 1) {
name
email
}
}
# Yangi user yaratish
mutation {
createUser(input: { name: "Vali", email: "vali@test.com" }) {
id
name
}
}
Tez-tez uchraydigan xatolar
1. Schema xatosi
Cannot determine GraphQL output type for "users"
Sababi: @Field() dekoratori yo'q yoki @ObjectType() unutilgan.
Yechim: Barcha maydonlarga @Field() qo'ying, klassga @ObjectType() qo'ying.
2. Null xato
Cannot return null for non-nullable field User.name
Sababi: DB dan null keldi, lekin schema da String! (null bo'lmaydi deb belgilangan).
Yechim: @Field({ nullable: true }) yoki DB dan ma'lumot to'g'ri kelishini tekshiring.
3. Playground ko'rinmayapti
Sababi: Production muhitda playground avtomatik o'chadi.
Yechim: GraphQLModule.forRoot({ playground: true }) — faqat development da.
Xulosa
@ObjectType()— GraphQL tipi (REST da model)@InputType()— mutation uchun kiritma@Query()— ma'lumot olish (REST da GET)@Mutation()— o'zgartirish (REST da POST/PUT)autoSchemaFile— TypeScript dan schema avtomatik yaratiladi- Playground —
http://localhost:3000/graphqlda sinab ko'rish
Keyingi dars: 44-dars: Event Emitter