IlmHamroh
JavaScript Full-stack/29-qism. Backend integratsiyalar: fayl, to'lov, bot, realtime57/69-dars15 daqiqa
Mundarija (22)

OpenAPI 3.1 spetsifikatsiyasi: API shartnomasini yozish

Qisqacha: OpenAPI — HTTP API'ni mashina o'qiy oladigan formatda (YAML yoki JSON) tasvirlash standarti: qaysi yo'llar bor, qanday parametr va tana kutiladi, qanday javoblar qaytadi. Bitta hujjatdan interaktiv hujjat sahifasi, frontend uchun tipli klient, so'rov validatsiyasi va kontrakt testlar olinadi. 3.1 versiyasi sxemalarda to'liq JSON Schema 2020-12 ni ishlatadi — masalan null qiymat nullable: true bilan emas, type: ["string", "null"] bilan yoziladi.

Bu darsda

  • OpenAPI va Swagger nomlari orasidagi farqni va versiyalar tarixini bilasiz.
  • Hujjatning asosiy qismlarini — info, servers, paths, components, security — yozasiz.
  • parameters, requestBody va responses bilan bitta amalni to'liq tasvirlaysiz.
  • $ref va components/schemas bilan sxemalarni qayta ishlatasiz va JS'da $ref ni ochasiz.
  • 3.0 dan 3.1 ga o'tishdagi asosiy farqlarni (nullable, exclusiveMinimum) tushuntirasiz.

Oldin bilishingiz kerak: REST prinsiplari va resurslar, Xato javoblari: Problem Details, Zod 4 serverda (toJSONSchema), API dizayn qo'llanmalari va konvensiyalar.

1. Nega bu kerak?

25-qismda vazifalar-api uchun API.md yozgandik: qo'lda, oddiy matn bilan. "GET /v1/vazifalar/:id — vazifani qaytaradi, topilmasa 404". Uni odam o'qiydi. Lekin uchta muammo bor.

Birinchisi — eskirish. Dasturchi kodga yangi maydon qo'shdi, API.md ni unutdi. Bir oydan keyin hujjat va kod boshqa-boshqa narsani aytadi. Ikkinchisi — frontend tiplari. vazifalar frontendi Vazifa tipini qo'lda yozgan (19-qism). Backend muddat ni null qila boshlasa, frontend bilmaydi. Uchinchisi — mobil jamoa, hamkorlar, test yozuvchilar: hammasi API'ni o'z tilida qayta tasvirlaydi.

OpenAPI shu muammolarni yechadi: API'ning shartnomasi (contract) bitta, mashina o'qiy oladigan faylda. Undan avtomatik ravishda:

  • interaktiv hujjat sahifasi (Swagger UI, Scalar, Redoc);
  • TypeScript tiplari va tayyor klient funksiyalari;
  • kiruvchi so'rovni validatsiya qiluvchi middleware;
  • kontrakt testlar va "breaking change" tekshiruvi

olinadi. Bu darsda formatning o'zini o'rganamiz. Keyingi darsda hujjatni koddan yasaymiz va undan klient generatsiya qilamiz.

2. OpenAPI, Swagger va versiyalar

Ikki nom ko'p chalkashtiriladi:

  • Swagger — 2011-yilda boshlangan format va vositalar to'plami. 2015-yilda SmartBear format huquqlarini Linux Foundation'ga topshirdi, format OpenAPI deb qayta nomlandi. Swagger 2.0 = OpenAPI 2.0.
  • Bugun OpenAPI — spetsifikatsiya (OpenAPI Initiative boshqaradi), Swagger esa SmartBear'ning vositalari: Swagger UI, Swagger Editor, Swagger Codegen. "Swagger hujjati" deyilsa, odatda OpenAPI hujjati nazarda tutiladi.
Versiya Asosiy o'zgarish
2.0 (Swagger) definitions, host, basePath
3.0.x components, requestBody, servers; JSON Schema'ning o'z "lahjasi"
3.1.x to'liq JSON Schema 2020-12, webhooks, paths ixtiyoriy
3.2.0 eng yangisi (2025): yangi imkoniyatlar, 3.1 bilan moslik saqlangan

Bu darsda 3.1 ni o'rganamiz: vositalar uni keng qo'llab-quvvatlaydi va kanon ham 3.1 hujjat yasagan. 3.2 hujjati 3.1 ning ustiga qurilgan — bu yerda o'rgangan hamma narsa unda ham amal qiladi. Vositangiz qaysi versiyani tushunishini doim tekshiring.

3. Hujjat skeleti

OpenAPI hujjati — bitta YAML yoki JSON fayl (odatda openapi.yaml). YAML odam uchun qulayroq, JSON — dastur uchun. Ma'nosi bir xil. Eng kichik to'liq hujjat:

yaml
openapi: 3.1.0
info:
  title: vazifalar-api
  version: 3.0.0
servers:
  - url: http://127.0.0.1:3000
paths:
  /v1/salomatlik:
    get:
      summary: Server ishlayaptimi
      responses:
        "200":
          description: OK
Maydon Ma'nosi
openapi spetsifikatsiya versiyasi (majburiy)
info API nomi va API'ning o'z versiyasi (majburiy)
servers bazaviy URL'lar (dev, staging, prod)
paths yo'llar va ularning amallari
components qayta ishlatiladigan sxemalar, javoblar, xavfsizlik
security sukut xavfsizlik talabi
webhooks API o'zi yuboradigan so'rovlar (3.1 da yangi)

E'tibor bering: openapi: 3.1.0 — format versiyasi, info.version: 3.0.0 — vazifalar-api ning versiyasi. Ular bir-biriga bog'liq emas.

webhooks — Chiquvchi webhook'larni yuborish darsidagi narsa: API qanday so'rov yuborishini mijoz oldindan biladi.

4. paths: bitta amalni to'liq tasvirlash

4.1 Amal (operation)

paths ichida yo'l, yo'l ichida HTTP metod. Metod ostidagi obyekt — operation (amal). GET /v1/vazifalar/{id} ni to'liq yozamiz:

yaml
paths:
  /v1/vazifalar/{id}:
    get:
      operationId: vazifaOlish
      summary: Vazifani olish
      tags: [vazifalar]
      security:
        - cookieAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
            exclusiveMinimum: 0
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Vazifa"
        "404":
          description: Topilmadi
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"

Qatorma-qator:

  • operationId — amalning noyob nomi. Klient generatorlari undan funksiya nomi yasaydi (vazifaOlish()). Bo'lmasa, generator yo'ldan noqulay nom o'ylab topadi.
  • tags — hujjat sahifasida guruhlash.
  • parameters — in to'rt xil: path ({id}), query (?q=), header, cookie. Path parametri doim required: true.
  • responses — status kod bo'yicha. Kalitlar qo'shtirnoqda ("200"): YAML'da 200 son bo'lib ketadi, spetsifikatsiya esa satr talab qiladi.
  • content — media turi bo'yicha. 404 javobi application/problem+json — Problem Details darsidagi format.

4.2 requestBody

POST uchun tana tasviri:

yaml
  /v1/vazifalar:
    post:
      operationId: vazifaYaratish
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/YangiVazifa"
      responses:
        "201":
          description: Yaratildi
          headers:
            Location:
              schema: { type: string }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Vazifa"
        "422":
          $ref: "#/components/responses/Validatsiya"

requestBody.required: true — tanasiz so'rov xato. headers — javob sarlavhalari (201 da Location). "422": $ref — butun javob ham components/responses dan qayta ishlatiladi: bir xil validatsiya xatosi o'nlab amalda takrorlanmaydi.

Tekshirib ko'ring: GET /v1/vazifalar?sahifa=2 dagi sahifa ni qayerda tasvirlaysiz?

Javob

parameters ichida in: query bilan: { name: sahifa, in: query, required: false, schema: { type: integer, minimum: 1, default: 1 } }. Query parametrlar odatda ixtiyoriy va default ga ega. Kursor sahifalashda (Pagination) kursor — type: string, chunki u shaffof bo'lmagan satr.

5. components va $ref

5.1 Sxemalar

Qayta ishlatiladigan hamma narsa components ostida: schemas, responses, parameters, requestBodies, headers, securitySchemes. Ularga $ref bilan murojaat qilinadi: "#/components/schemas/Vazifa" — "shu hujjatning (#) components → schemas → Vazifa yo'li". Bu — JSON Pointer (RFC 6901) sintaksisi.

Kanon Vazifa sxemasini Zod'dan generatsiya qilgan (zod-to-openapi 9.1.0; qanday — keyingi darsda). Natijadagi sxema, biz qayta ishga tushirib formatladik:

json
{
  "type": "object",
  "properties": {
    "id": { "type": "integer", "example": 42 },
    "matn": { "type": "string", "minLength": 1, "maxLength": 100 },
    "bajarildi": { "type": "boolean" },
    "muddat": { "type": ["string", "null"], "format": "date-time" }
  },
  "required": ["id", "matn", "bajarildi"],
  "description": "Bitta vazifa"
}

Bu — oddiy JSON Schema. Ikki narsaga e'tibor bering:

  • muddat required ro'yxatida yo'q — maydon umuman bo'lmasligi mumkin. Va bor bo'lsa, null ham bo'lishi mumkin. "Yo'q" va "null" — ikki xil holat (Validatsiya: nima uchun, qayerda va qanday darsidagi optional va nullable farqi).
  • format: date-time — validatsiya emas, izoh. JSON Schema 2020-12 bo'yicha format sukut bo'yicha faqat annotatsiya; validator uni tekshirishi uchun alohida yoqiladi (Ajv'da ajv-formats).

5.2 3.0 va 3.1: nullable

OpenAPI 3.0 JSON Schema'ning o'z variantini ishlatardi va null uchun maxsus kalit bor edi:

yaml
# OpenAPI 3.0
muddat:
  type: string
  nullable: true
yaml
# OpenAPI 3.1 (JSON Schema 2020-12)
muddat:
  type: [string, "null"]

3.1 da nullable kaliti yo'q — u e'tiborsiz qoldiriladi yoki validator xato beradi. Kanon generatsiya qilgan hujjatda ham aynan {"type": ["string", "null"]}. Ikkinchi farq — exclusiveMinimum: 3.0 da u boolean (minimum: 0, exclusiveMinimum: true), 3.1 da — son (exclusiveMinimum: 0). Yuqoridagi id parametrida aynan shunday. 3.0 hujjatini 3.1 deb belgilab qo'yish — keng tarqalgan xato: hujjat "ochiladi", lekin null qabul qiladigan maydonlar endi qabul qilmaydi.

5.3 $ref ni ochish

Vositalar $ref ni qanday ochishini o'zimiz yozib ko'raylik. Hujjat — oddiy JS obyekti, $ref — yo'l:

js
const hujjat = {
  paths: {
    "/v1/vazifalar/{id}": {
      get: {
        responses: {
          200: { $ref: "#/components/responses/VazifaOK" },
        },
      },
    },
  },
  components: {
    responses: {
      VazifaOK: {
        description: "OK",
        content: {
          "application/json": {
            schema: { $ref: "#/components/schemas/Vazifa" },
          },
        },
      },
    },
    schemas: {
      Vazifa: { type: "object", required: ["id", "matn"] },
    },
  },
};

function och(ref, ildiz) {
  if (!ref.startsWith("#/")) throw new Error(`tashqi $ref: ${ref}`);
  return ref
    .slice(2)
    .split("/")
    .map((q) => q.replaceAll("~1", "/").replaceAll("~0", "~"))
    .reduce((obj, kalit) => {
      if (obj?.[kalit] === undefined) {
        throw new Error(`topilmadi: ${ref}`);
      }
      return obj[kalit];
    }, ildiz);
}

function tozala(qism, ildiz) {
  if (Array.isArray(qism)) return qism.map((x) => tozala(x, ildiz));
  if (qism && typeof qism === "object") {
    if (typeof qism.$ref === "string") {
      return tozala(och(qism.$ref, ildiz), ildiz);
    }
    return Object.fromEntries(
      Object.entries(qism).map(([k, v]) => [k, tozala(v, ildiz)]),
    );
  }
  return qism;
}

const amal = hujjat.paths["/v1/vazifalar/{id}"].get;
console.log(JSON.stringify(tozala(amal, hujjat)));
try {
  och("#/components/schemas/Foydalanuvchi", hujjat);
} catch (e) {
  console.log(e.message);
}

Konsolda:

text
{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["id","matn"]}}}}}}
topilmadi: #/components/schemas/Foydalanuvchi

Ikki qavatli $ref (javob → sxema) to'liq ochildi. ~1 va ~0 — JSON Pointer'ning qochirish qoidasi: kalit ichidagi / va ~ uchun (/v1/vazifalar yo'lining o'ziga $ref qilish kerak bo'lsa — #/paths/~1v1~1vazifalar). Haqiqiy vositalar ikki narsani qo'shimcha hal qiladi: tashqi fayllar ($ref: "./sxemalar/vazifa.yaml") va aylanma havolalar (Foydalanuvchi.vazifalar[].egasi → Foydalanuvchi). Bizning tozala aylanma havolada cheksiz aylanardi.

6. Xavfsizlik sxemalari

securitySchemes — API qanday himoyalanganini tasvirlaydi. Kanon cookie sessiyasini shunday yozgan (hujjatdan):

json
"securitySchemes": {
  "cookieAuth": {
    "type": "apiKey",
    "in": "cookie",
    "name": "__Host-sessiya"
  }
}
type Qachon Misol
apiKey kalit sarlavha, query yoki cookie'da X-API-Key, sessiya cookie
http Authorization sarlavhasi scheme: bearer, bearerFormat: JWT
oauth2 OAuth oqimlari flows.authorizationCode
openIdConnect OIDC discovery URL Google, OneID

Sxema e'lon qilingach, amal yoki butun hujjat darajasida talab qilinadi: security: [{ cookieAuth: [] }]. Ochiq amal uchun — security: [] (bo'sh massiv sukutni bekor qiladi). Sessiya va JWT'ning o'zi 28-qismda; bu yerda faqat ularni tasvirlash.

Diqqat: OpenAPI hujjati — ommaviy hujjat bo'lishi mumkin. Unga haqiqiy kalit, token, ichki server manzili yoki admin amallarini yozmang. Ichki amallar uchun alohida hujjat yoki ularni chiqarib tashlang.

7. Spec-first yoki code-first?

Hujjat qanday paydo bo'ladi? Ikki yo'l bor:

flowchart LR
  subgraph S["Spec-first"]
    Y["openapi.yaml qo'lda"] --> K1["Server kodi"]
    Y --> F1["Klient va tiplar"]
  end
  subgraph C["Code-first"]
    Z["Zod sxemalari va marshrutlar"] --> Y2["openapi.json avtomatik"]
    Y2 --> F2["Klient va tiplar"]
  end
Spec-first Code-first
Manba YAML fayl kod (Zod, dekoratorlar)
Afzallik jamoalar kod yozilmasdan kelishadi hujjat kod bilan doim mos
Kamchilik kod va hujjat ajralib ketishi mumkin dizayn kod ichida "yashiringan"
Qachon ko'p jamoa, ochiq API, hamkorlar bitta jamoa, TS backend

Kanon code-first ni tanladi: vazifalar-api da sxemalar allaqachon Zod'da, ikkinchi manba ortiqcha. Buni keyingi darsda qilamiz. NestJS (30-qism) ham code-first: dekoratorlardan Swagger hujjati.

8. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
null maydon validatsiyadan o'tmaydi 3.1 hujjatda 3.0 dagi nullable: true type: [string, "null"]
YAML'da 200: xato beradi kalit son bo'lib ketdi "200": qo'shtirnoqda
Generator getV1VazifalarId kabi nom berdi operationId yo'q har amalga operationId
Hujjat kod bilan mos emas qo'lda yozilgan, yangilanmagan code-first yoki CI'da kontrakt test
format: email tekshirilmaydi format — annotatsiya validatorda formatlarni yoqing
Ochiq amal ham "qulf" bilan hujjat darajasidagi security amalda security: []

9. Mashqlar

Mashqlar kurs/mashqlar/29/57-openapi/ da.

1-mashq (oson): bo'shliqlarni to'ldiring

  • Qayta ishlatiladigan sxemalar joyi — components/
  • 3.1 da null ruxsati — type: [string, " "]
  • Klient funksiya nomi olinadigan maydon —
  • Parametr joylari: path, query, header va
  • Swagger 2.0 ning yangi nomi — OpenAPI
Yechim
  • schemas — $ref: "#/components/schemas/Vazifa".
  • null — JSON Schema 2020-12 uslubi.
  • operationId — noyob bo'lishi shart.
  • cookie — in: cookie.
  • 2.0 — 2015-yildan OpenAPI.

2-mashq (o'rta): amallar ro'yxati

amallar(hujjat) funksiyasini yozing: u hujjatdagi har amal uchun "GET /v1/vazifalar/{id} vazifaOlish 🔒" ko'rinishidagi qator qaytarsin. 🔒 — amal himoyalangan bo'lsa: amalning o'z security i bo'sh bo'lmagan massiv, yoki amalda security yo'q va hujjat darajasidagi security bo'sh emas. operationId yo'q bo'lsa — (nomsiz). Faqat HTTP metod kalitlarini oling (parameters kabi umumiy kalitlarni emas).

Yechim
js
const METODLAR = [
  "get", "put", "post", "delete", "patch", "head", "options",
];

function amallar(hujjat) {
  const sukut = hujjat.security ?? [];
  const natija = [];
  for (const [yol, element] of Object.entries(hujjat.paths ?? {})) {
    for (const [metod, amal] of Object.entries(element)) {
      if (!METODLAR.includes(metod)) continue;
      const talab = amal.security ?? sukut;
      const qulf = talab.length > 0 ? " 🔒" : "";
      const nom = amal.operationId ?? "(nomsiz)";
      natija.push(`${metod.toUpperCase()} ${yol} ${nom}${qulf}`);
    }
  }
  return natija;
}

const hujjat = {
  openapi: "3.1.0",
  security: [{ cookieAuth: [] }],
  paths: {
    "/v1/salomatlik": {
      get: { operationId: "salomatlik", security: [] },
    },
    "/v1/vazifalar": {
      parameters: [{ name: "q", in: "query" }],
      get: { operationId: "vazifalarRoyxati" },
      post: { operationId: "vazifaYaratish" },
    },
    "/v1/vazifalar/{id}": { delete: {} },
  },
};
for (const q of amallar(hujjat)) console.log(q);

Konsolda:

text
GET /v1/salomatlik salomatlik
GET /v1/vazifalar vazifalarRoyxati 🔒
POST /v1/vazifalar vazifaYaratish 🔒
DELETE /v1/vazifalar/{id} (nomsiz) 🔒

salomatlik ochiq: security: [] sukutni bekor qildi. parameters — yo'l darajasidagi umumiy parametrlar, u amal emas, shuning uchun o'tkazildi. DELETE da operationId yo'q — haqiqiy loyihada buni lint vositasi (keyingi darsda Spectral) ushlaydi.

3-mashq (qiyin): kichik sxema validatori

tekshir(qiymat, sxema) yozing: u xatolar massivini qaytarsin (["matn: minLength 1"] kabi, yo'l bilan). Qo'llab-quvvatlang: type (satr yoki massiv; integer — butun son, null), required, properties, minLength, maxLength. Ichki obyektlar uchun yo'l nuqta bilan (egasi.ism). Darsdagi Vazifa sxemasi bilan to'rtta qiymatni sinang.

Yechim
js
function turi(v) {
  if (v === null) return "null";
  if (Array.isArray(v)) return "array";
  if (Number.isInteger(v)) return "integer";
  return typeof v;
}

function mos(v, kerak) {
  const t = turi(v);
  return t === kerak || (kerak === "number" && t === "integer");
}

function tekshir(v, sxema, yol = "") {
  const x = [];
  const nom = yol || "(ildiz)";
  if (sxema.type) {
    const turlar = [sxema.type].flat();
    if (!turlar.some((k) => mos(v, k))) {
      return [`${nom}: type ${turlar.join("|")}, keldi ${turi(v)}`];
    }
  }
  if (typeof v === "string") {
    if (v.length < (sxema.minLength ?? 0)) {
      x.push(`${nom}: minLength ${sxema.minLength}`);
    }
    if (v.length > (sxema.maxLength ?? Infinity)) {
      x.push(`${nom}: maxLength ${sxema.maxLength}`);
    }
  }
  if (turi(v) === "object") {
    for (const k of sxema.required ?? []) {
      if (!(k in v)) x.push(`${yol ? yol + "." : ""}${k}: majburiy`);
    }
    for (const [k, s] of Object.entries(sxema.properties ?? {})) {
      const ichki = yol ? `${yol}.${k}` : k;
      if (k in v) x.push(...tekshir(v[k], s, ichki));
    }
  }
  return x;
}

const Vazifa = {
  type: "object",
  properties: {
    id: { type: "integer" },
    matn: { type: "string", minLength: 1, maxLength: 100 },
    bajarildi: { type: "boolean" },
    muddat: { type: ["string", "null"] },
  },
  required: ["id", "matn", "bajarildi"],
};

const qiymatlar = [
  { id: 1, matn: "Non", bajarildi: false },
  { id: 1.5, matn: "", muddat: null },
  { id: 2, matn: "Sut", bajarildi: true, muddat: 0 },
  [1, 2],
];
for (const q of qiymatlar) console.log(tekshir(q, Vazifa));

Konsolda:

text
[]
[
  'bajarildi: majburiy',
  'id: type integer, keldi number',
  'matn: minLength 1'
]
[ 'muddat: type string|null, keldi integer' ]
[ '(ildiz): type object, keldi array' ]

muddat: null xatosiz o'tdi — type: ["string", "null"]. muddat: 0 esa yo'q. id: 1.5 — integer emas. Bu o'quv validatori: haqiqiy loyihada JSON Schema 2020-12 ni to'liq biladigan Ajv ishlatiladi ($ref, oneOf, format, additionalProperties). Ko'pincha esa umuman alohida validator kerak emas: Zod sxemasi ham hujjat manbai, ham validator — keyingi dars shu haqda.

10. Loyiha qadami: kanon tajribasi, loyihaga kirmaydi

Kurs rejasi bo'yicha OpenAPI vazifalar-api ga qo'shilmaydi. Kanon 3.1 hujjatini tajribada yasadi (bitta amal, Vazifa va Problem sxemalari, cookie xavfsizlik sxemasi — 1 141 bayt). Loyihada esa API hujjati 30-qismda NestJS bilan qayta quriladi va Swagger o'sha yerda avtomatik chiqadi. Ikki marta qilmaslik uchun bu yerda faqat tajriba.

O'zingiz sinab ko'ring: vazifalar-api ning API.md sidagi uchta amalni (GET /v1/vazifalar, POST /v1/vazifalar, GET /v1/vazifalar/{id}) qo'lda openapi.yaml ga yozing. Uni Swagger Editor (editor.swagger.io) yoki Scalar'ning onlayn muharririda oching va xatolarini tuzating. Hujjatga haqiqiy server manzili yoki kalit yozmang.

11. Real ishda

  • Ochiq API'lar — Stripe, GitHub, Telegram'ning ba'zi klientlari OpenAPI hujjatidan yasaladi. To'lov tizimlari hamkorlarga ko'pincha OpenAPI fayl beradi.
  • Mikroservislar — har servis o'z shartnomasini e'lon qiladi, boshqalar undan klient yasaydi.
  • API gateway'lar (Kong, AWS API Gateway) OpenAPI faylni import qilib, marshrut va validatsiyani sozlaydi.
  • AI agentlar — LLM'ga "qaysi API'ni qanday chaqirish mumkin" deb OpenAPI tavsifi beriladi (tool calling, 31-qism).
  • Intervyuda: "OpenAPI va Swagger farqi?", "Spec-first va code-first?", "3.0 dan 3.1 ga o'tishda nima o'zgaradi?"

Xulosa

  • OpenAPI — API shartnomasi: YAML/JSON, openapi, info, paths, components; Swagger — vositalar nomi.
  • Amal: operationId, parameters (path/query/header/cookie), requestBody, responses (kalit — satr).
  • components + $ref (JSON Pointer) — bir sxema ko'p joyda.
  • 3.1 = JSON Schema 2020-12: type: [string, "null"], exclusiveMinimum — son; format — annotatsiya.
  • securitySchemes faqat tasvirlaydi; ochiq amal — security: [].
  • Kanon: code-first; vazifalar-api ga OpenAPI qo'shilmaydi — 30-qismda NestJS Swagger.

Keyingi dars: Code-first OpenAPI va klient generatsiyasi — Zod sxemalaridan hujjat yasaymiz, undan TypeScript tiplari chiqaramiz va breaking change'ni avtomatik aniqlaymiz.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!