Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

Follow publication

Creating a basic REST API with Node.js, Swagger MVC

In this tutorial, we’ll explore the development of a RESTful API using the Model-View-Controller (MVC) architectural pattern. MVC divides the application into three components: Models for data management, Views for presentation, and Controllers for request handling and interaction orchestration. This structured approach ensures scalability and maintainability. Additionally, we’ll integrate Swagger to document and interact with our API seamlessly, enhancing its accessibility and understanding.

Structure:

my-api/
├── controllers/
│ └── itemController.js
├── models/
│ └── itemModel.js
├── routes/
│ └── itemRoutes.js
├── items.json
├── swaggerConfig.js
├── index.js
└── package.json

Code:

npm init -y
npm install express body-parser
npm install swagger-ui-express swagger-jsdoc
npm install --save-dev nodemon

package.json:

{
"name": "backend",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"body-parser": "^1.20.2",
"express": "^4.19.2",
"fs": "^0.0.1-security",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.0"
},
"devDependencies": {
"nodemon": "^3.1.0"
}
}

swaggerConfig.js:

// swaggerConfig.js
const swaggerJsdoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

// Swagger definition
const swaggerDefinition = {
openapi: '3.0.0',
info: {
title: 'My API',
version: '1.0.0',
description: 'Documentation for my API',
},
servers: [{
url: 'http://localhost:3000', // Replace with your server URL
description: 'Development server',
}],
};

// Options for the swagger-jsdoc
const options = {
swaggerDefinition,
// Paths to files containing OpenAPI definitions
apis: ['./routes/*.js'], // Path to the API routes folder
};

// Initialize swagger-jsdoc
const swaggerSpec = swaggerJsdoc(options);

module.exports = { swaggerUi, swaggerSpec };

items.json:

[
{
"id": 1,
"name": "Item 1"
},
{
"id": 2,
"name": "Item 2"
},
{
"id": 3,
"name": "Item 3"
},
{
"id": 4,
"name": "Item 4"
}
]

index.js:

// index.js
const express = require('express');
const bodyParser = require('body-parser');
const itemRoutes = require('./routes/itemRoutes');
const { swaggerUi, swaggerSpec } = require('./swaggerConfig'); // Import Swagger configuration

const app = express();
const PORT = process.env.PORT || 3000;

app.use(bodyParser.json());

// Serve Swagger UI
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));

// Routes
app.use('/api/items', itemRoutes);

app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});

itemRoutes.js:

// itemRoutes.js
const express = require('express');
const router = express.Router();
const itemController = require('../controllers/itemController');

/**
* @swagger
* /api/items:
* get:
* summary: Get all items
* responses:
* 200:
* description: Returns all items
* content:
* application/json:
* schema:
* type: array
* items:
* $ref: '#/components/schemas/Item'
*/

router.get('/', itemController.getAllItems);

/**
* @swagger
* /api/items/{id}:
* get:
* summary: Get an item by ID
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the item to get
* responses:
* 200:
* description: Returns the specified item
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Item'
* 404:
* description: Item not found
*/

router.get('/:id', itemController.getItemById);

/**
* @swagger
* /api/items:
* post:
* summary: Add a new item
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Item'
* responses:
* 201:
* description: New item created
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Item'
*/

router.post('/', itemController.addItem);

module.exports = router;

itemController.js:

// itemController.js
const Item = require('../models/itemModel');

module.exports = {

getAllItems(req, res) {
const items = Item.getAllItems();
res.json(items);
},
getItemById(req, res) {
const id = parseInt(req.params.id);
const item = Item.getItemById(id);
if (!item) return res.status(404).send('Item not found');
res.json(item);
},
addItem(req, res) {
const newItem = req.body;
const item = Item.addItem(newItem);
res.status(201).json(item);
}
// Add other controller functions as needed
};

ItemModel.js:

const fs = require('fs');


const filePath = './items.json';


function loadItems() {
try {
const data = fs.readFileSync(filePath);
return JSON.parse(data);
} catch (error) {

return [];
}
}


function saveItems(items) {
fs.writeFileSync(filePath, JSON.stringify(items, null, 4));
}

module.exports = {
getAllItems() {
return loadItems();
},
getItemById(id) {
const items = loadItems();
return items.find(item => item.id === id);
},
addItem(item) {
const items = loadItems();
items.push(item);
saveItems(items);
return item;
},

};
npm run dev

http://localhost:3000/api-docs/

http://localhost:3000/api/items/

http://localhost:3000/api/items/1

Don’t hesitate to give more applause 👏🏻 and share the article with whoever you want. As always, I appreciate your support, I will continue with more tutorials.

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

Written by Alberto R.

Final-semester Systems Engineering student, passionate about web/software development, exploring new technologies, creative solutions, and organizing activities

No responses yet

Write a response