API dokumentatsiya — Swagger bilan
Muammodan boshlaylik
Backend tayyor. Frontend dasturchi sizga yozadi:
"Qaysi endpointlar bor? Qanday parametrlar yuborish kerak? Javob qanday ko'rinadi? Token qayerga qo'yiladi?"
Siz har safar tushuntirasiz. Yoki Notion da yozasiz — kod o'zgarganda Notion eskirib qoladi. Yoki README yozasiz — uni hech kim o'qimaydi.
Swagger — bu muammoning yechimi. Kod yonida yashaydi, har doim yangi, o'zi interaktiv interfeys yaratadi. Frontend dasturchi brauzerdan endpointni sinab ko'ra oladi.
Swagger nima?
Swagger (OpenAPI) — API ni tasvirlash uchun standart format. swagger-ui-express esa bu tavsifni chiroyli interaktiv sahifaga aylantiradi.
npm install swagger-ui-express swagger-jsdoc
Arxitektura
project/
├── config/
│ └── swagger.js ← Swagger sozlamalari
├── routes/
│ └── products.js ← endpointlar (JSDoc izohlar shu yerda)
└── app.js
1-qadam: Swagger sozlamasi
// config/swagger.js
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'Mening API',
version: '1.0.0',
description: 'Express API dokumentatsiyasi',
},
servers: [
{ url: 'http://localhost:3000/api/v1' },
],
components: {
securitySchemes: {
bearerAuth: { // ← JWT token uchun
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
},
},
apis: ['./routes/*.js'], // ← izohlar qayerda
};
module.exports = swaggerJsdoc(options);
2-qadam: app.js ga ulash
// app.js
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = require('./config/swagger');
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
// → http://localhost:3000/api-docs — dokumentatsiya sahifasi
3-qadam: Route izohlar
Izohlar route faylida, endpoint ustida yoziladi. /** ... */ formatida:
// routes/products.js
/**
* @swagger
* /products:
* get:
* summary: Barcha mahsulotlar
* description: Filtr va sort bilan mahsulotlar ro'yxati
* tags: [Mahsulotlar]
* parameters:
* - in: query
* name: category
* schema:
* type: string
* description: Kategoriya nomi
* - in: query
* name: minPrice
* schema:
* type: number
* description: Minimal narx
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: Sahifa raqami
* responses:
* 200:
* description: Muvaffaqiyatli
* content:
* application/json:
* example:
* success: true
* data:
* - id: "64f1a2b3"
* name: "iPhone 15"
* price: 1200000
* meta:
* page: 1
* total: 50
*/
router.get('/', async (req, res, next) => {
// ...
});
/**
* @swagger
* /products/{id}:
* get:
* summary: Bitta mahsulot
* tags: [Mahsulotlar]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* description: Mahsulot ID si
* responses:
* 200:
* description: Mahsulot topildi
* content:
* application/json:
* example:
* success: true
* data:
* id: "64f1a2b3"
* name: "iPhone 15"
* price: 1200000
* 404:
* description: Topilmadi
* content:
* application/json:
* example:
* success: false
* error:
* code: NOT_FOUND
* message: "Mahsulot topilmadi"
*/
router.get('/:id', async (req, res, next) => {
// ...
});
/**
* @swagger
* /products:
* post:
* summary: Yangi mahsulot yaratish
* tags: [Mahsulotlar]
* security:
* - bearerAuth: [] ← token kerak
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [name, price]
* properties:
* name:
* type: string
* example: "iPhone 15"
* price:
* type: number
* example: 1200000
* category:
* type: string
* example: "elektronika"
* responses:
* 201:
* description: Yaratildi
* content:
* application/json:
* example:
* success: true
* data:
* id: "64f1a2b3"
* name: "iPhone 15"
* price: 1200000
* 401:
* description: Token kerak
* 422:
* description: Validatsiya xatosi
*/
router.post('/', auth, async (req, res, next) => {
// ...
});
Schema qayta ishlatish (takrorlanishni kamaytirish)
Bir xil obyekt tuzilishi ko'p joyda ishlatilsa — alohida schema yarating:
// routes/products.js yuqorisida
/**
* @swagger
* components:
* schemas:
* Product:
* type: object
* properties:
* id:
* type: string
* example: "64f1a2b3"
* name:
* type: string
* example: "iPhone 15"
* price:
* type: number
* example: 1200000
* category:
* type: string
* example: "elektronika"
*/
Keyin response da qayta ishlating:
/**
* @swagger
* /products/{id}:
* get:
* responses:
* 200:
* content:
* application/json:
* schema:
* properties:
* data:
* $ref: '#/components/schemas/Product' ← qayta ishlatish
*/
Natija
http://localhost:3000/api-docs da shunday ko'rinadi:
┌─────────────────────────────────────┐
│ Mening API v1.0.0 │
├─────────────────────────────────────┤
│ ▼ Mahsulotlar │
│ ┌─────────────────────────────┐ │
│ │ GET /products [Try it] │ │
│ │ POST /products [Try it] │ │
│ │ GET /products/{id} [Try] │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
"Try it out" tugmasini bosib, to'g'ridan-to'g'RI brauzerdan so'rov yuborish mumkin. Token ham kiritiladi — hamma narsa interaktiv.
Tez-tez uchraydigan xatolar
1. YAML chekinishiga e'tibor bermaslik
// ❌ — YAML da chekinish (indentation) muhim
/**
* @swagger
* /products:
* get: ← 1 bo'shliq — noto'g'ri
* summary: ...
*/
// ✅ — 2 yoki 4 bo'shliq, izchil
/**
* @swagger
* /products:
* get: ← 2 bo'shliq — to'g'ri
* summary: ...
*/
Sababi: Swagger YAML formatini ishlatadi. Chekinish noto'g'ri bo'lsa — parse xatosi, dokumentatsiya ko'rinmaydi.
2. apis yo'li noto'g'ri
// ❌ — fayl topilmasa izohlar o'qilmaydi
apis: ['./route/*.js'] // ← "route" emas, "routes"
// ✅
apis: ['./routes/*.js', './routes/**/*.js'], // ← ichki papkalar ham
3. Dokumentatsiyani production da ochiq qoldirish
// ❌ — production da hamma ko'ra oladi
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
// ✅ — faqat development da
if (process.env.NODE_ENV !== 'production') {
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
}
Sababi: API tuzilishi, endpoint nomlari, parametrlar — bularni hamma ko'rishi xavfsizlik xatari.
Xulosa
- Swagger — API ni interaktiv dokumentatsiya sifatida ko'rsatadi
swagger-jsdocizohlarni o'qiydi,swagger-ui-expresssahifa ko'rsatadi- Izohlar route faylida, endpoint ustida
/** @swagger */formatida $ref— schemani qayta ishlatish, takrorlanishni kamaytiradi- Production da
/api-docsni yoping
Keyingi dars: 41-dars: Webhook — qabul qilish va yuborish