Swagger Practice
This tutorial will guide you to implement a Book Management System API based on Swagger, with the main features including:
* CRUD operations for books
* Pagination query
* Conditional filtering
* Automatic API documentation generation
* Online interface testing
Tech Stack:
* Node.js + Express
* Swagger UI Express
* Swagger JSDoc
* * *
## Environment Setup
### Install Node.js
Make sure Node.js is installed on your system (v14.0.0 or higher is recommended).
### Check Environment
node -v npm -v
* * *
## Project Initialization
### Create Project Directory
mkdir book-management-api cd book-management-api npm init -y
### Install Dependencies
npm install express cors swagger-ui-express swagger-jsdoc nodemon --save
### Create Basic Project Structure
book-management-api/βββ node_modules/βββ models/β βββ book.js βββ routes/β βββ books.js βββ middleware/β βββ auth.js βββ swagger/β βββ swagger.js βββ app.js βββ package.json
### Create Entry File app.js
## Example
const express = require('express');
const cors = require('cors');
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = require('./swagger/swagger');
const booksRouter = require('./routes/books');
const app = express();
const PORT = process.env.PORT||3000;
// Middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended:true}));
// API Routes
app.use('/api/books', booksRouter);
// Swagger Documentation
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
// Start Server
app.listen(PORT,()=>{
console.log(`Service started, access http://localhost:${PORT}`);
console.log(`API documentation address: http://localhost:${PORT}/api-docs`);
});
* * *
## API Design and Implementation
### Create Book Model
Create a simple in-memory data model in `models/book.js`:
## Example
// models/book.js
let books =[
{ id:1, title:'Deep Understanding of JavaScript', author:'Douglas Crockford', publishDate:'2008-01-01', isbn:'978-0596517748', category:'programming'},
{ id:2, title:'Node.jsHands-on', author:'Alex Young', publishDate:'2014-08-01', isbn:'978-1617290572', category:'programming'},
{ id:3, title:'The Three-Body Problem', author:'Liu Cixin', publishDate:'2008-01-01', isbn:'978-7536692387', category:'Sci-Fi'}
];
let nextId =4;
module.exports={
// Get all books
getAll:(page =1, limit =10, filter ={})=>{
let result =[...books];
// Apply filter conditions
if(filter.category){
result = result.filter(book => book.category=== filter.category);
}
if(filter.author){
result = result.filter(book => book.author.includes(filter.author));
}
if(filter.title){
result = result.filter(book => book.title.includes(filter.title));
}
// Calculate pagination
const startIndex =(page -1)* limit;
const endIndex = page * limit;
return{
total: result.length,
page: page,
limit: limit,
data: result.slice(startIndex, endIndex)
};
},
// Get single book
getById:(id)=>{
return books.find(book => book.id=== id);
},
// Create book
create:(book)=>{
const newBook ={ ...book, id: nextId++};
books.push(newBook);
return newBook;
},
// Update book
update:(id, bookData)=>{
const index = books.findIndex(book => book.id=== id);
if(index !==-1){
books={ ...books, ...bookData};
return books;
}
return null;
},
// Delete book
delete:(id)=>{
const index = books.findIndex(book => book.id=== id);
if(index !==-1){
const deletedBook = books;
books.splice(index,1);
return deletedBook;
}
return null;
}
};
### Implement Route Controller
Implement API routes in `routes/books.js`:
## Example
// routes/books.js
const express = require('express');
const router = express.Router();
const Book = require('../models/book');
/**
* @swagger
* components:
* schemas:
* Book:
* type: object
* required:
* - title
* - author
* - isbn
* properties:
* id:
* type: integer
* description: Book ID
* title:
* type: string
* description: Book title
* author:
* type: string
* description: Author
* publishDate:
* type: string
* format: date
* description: Publication date
* isbn:
* type: string
* description: ISBN number
* category:
* type: string
* description: Book category
*/
/**
* @swagger
* /api/books:
* get:
* summary: Get book list
* description: Returns all books, supports pagination and filtering
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: Page number
* - in: query
* name: limit
* schema:
* type: integer
* default: 10
* description: Items per page
* - in: query
* name: category
* schema:
* type: string
* description: Filter by category
* - in: query
* name: author
* schema:
* type: string
* description: Filter by author
* - in: query
* name: title
* schema:
* type: string
* description: Filter by title
* responses:
* 200:
* description: Successfully retrieved book list
* content:
* application/json:
* schema:
* type: object
* properties:
* total:
* type: integer
* page:
* type: integer
* limit:
* type: integer
* data:
* type: array
* items:
* $ref: '#/components/schemas/Book'
*/
router.get('/',(req, res)=>{
const page = parseInt(req.query.page)||1;
const limit = parseInt(req.query.limit)||10;
const filter ={};
if(req.query.category) filter.category= req.query.category;
if(req.query.author) filter.author= req.query.author;
if(req.query.title) filter.title= req.query.title;
const result = Book.getAll(page, limit, filter);
res
YouTip