From e2fb0de6e5ca7ddc9a1b29a17af7b93ea3a3f106 Mon Sep 17 00:00:00 2001 From: LogicDX342 <52480482+LogicDX342@users.noreply.github.com> Date: Sat, 30 Mar 2024 15:32:56 +0800 Subject: [PATCH] Add swagger api documentation --- create_database.sql | 9 ---- server/package.json | 1 + server/pnpm-lock.yaml | 3 ++ server/src/models/index.js | 34 ++++++++----- server/src/models/user.js | 25 ++++++++++ server/src/routes/users.js | 37 +++++++------- server/src/server.js | 29 ++--------- server/src/swagger.js | 42 ++++++++++++++++ server/swagger-auto-generated.yaml | 77 ++++++++++++++++++++++++++++++ server/swagger.yaml | 77 ++++++++++++++++++++++++++++++ 10 files changed, 267 insertions(+), 67 deletions(-) delete mode 100644 create_database.sql create mode 100644 server/src/swagger.js create mode 100644 server/swagger-auto-generated.yaml create mode 100644 server/swagger.yaml diff --git a/create_database.sql b/create_database.sql deleted file mode 100644 index 82525bd..0000000 --- a/create_database.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE IF NOT EXISTS users -( - username varchar(20) NOT NULL, - password varchar(20) NOT NULL, - CONSTRAINT users_pk - PRIMARY KEY (username) -); - -INSERT INTO users (username, password) VALUES (lain, lain); \ No newline at end of file diff --git a/server/package.json b/server/package.json index 23866b9..b391331 100644 --- a/server/package.json +++ b/server/package.json @@ -14,6 +14,7 @@ "body-parser": "^1.20.2", "cors": "^2.8.5", "express": "^4.19.1", + "js-yaml": "^4.1.0", "mysql2": "^3.9.2", "sequelize": "^6.37.1", "swagger-jsdoc": "^6.2.8", diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index 7ce5a42..33bf66a 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -17,6 +17,9 @@ dependencies: express: specifier: ^4.19.1 version: 4.19.1 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 mysql2: specifier: ^3.9.2 version: 3.9.2 diff --git a/server/src/models/index.js b/server/src/models/index.js index e2085e4..1c1244f 100644 --- a/server/src/models/index.js +++ b/server/src/models/index.js @@ -1,17 +1,27 @@ -const Sequelize = require('sequelize'); -const UserModel = require('./user'); +const Sequelize = require("sequelize"); +const UserModel = require("./user"); -const sequelize = new Sequelize('mysql://root:123qweasd@localhost:3306/cs304_project'); -sequelize.authenticate() - .then(() => console.log('Connection has been established successfully.')) - .catch(err => console.error('Unable to connect to the database:', err)); +const sequelize = new Sequelize("cs304_project", "root", "123qweasd", { + host: "localhost", + dialect: "mysql", + logging: (msg) => { + if (msg.startsWith("Executing")) { + console.log(msg); + } + }, +}); +sequelize + .authenticate() + .then(() => + console.log("Connection to database has been established successfully.") + ) + .catch((err) => console.error("Unable to connect to the database:", err)); const User = UserModel(sequelize, Sequelize); -sequelize.sync({ force: false }) - .then(() => { - console.log(`Database & tables created!`) - }); +sequelize.sync({ force: false }).then(() => { + console.log(`Database & tables created!`); +}); module.exports = { - User -}; \ No newline at end of file + User, +}; diff --git a/server/src/models/user.js b/server/src/models/user.js index ab1f2cd..cd6592a 100644 --- a/server/src/models/user.js +++ b/server/src/models/user.js @@ -1,3 +1,28 @@ +/** + * @swagger + * components: + * schemas: + * User: + * type: object + * required: + * - username + * - password + * properties: + * id: + * type: integer + * description: The auto-generated id of the user + * readOnly: true + * username: + * type: string + * description: The username of the user + * password: + * type: string + * description: The password of the user + * example: + * id: 1 + * username: "user1" + * password: "pass1" + */ module.exports = (sequelize, type) => { return sequelize.define('user', { id: { diff --git a/server/src/routes/users.js b/server/src/routes/users.js index 18adfdc..2550fc9 100644 --- a/server/src/routes/users.js +++ b/server/src/routes/users.js @@ -3,29 +3,26 @@ const router = express.Router(); const { User } = require("../models"); /** - * @swagger + * @openapi * /users/register: * post: * summary: Register a user - * consumes: - * - application/json - * parameters: - * - in: body - * name: body - * description: User object - * required: true - * schema: - * type: object - * required: - * - username - * - password - * properties: - * username: - * type: string - * password: - * type: string + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - username + * - password + * properties: + * username: + * type: string + * password: + * type: string * responses: - * 200: + * '200': * description: User created successfully */ router.post("/register", async (req, res) => { @@ -59,7 +56,7 @@ router.post("/register", async (req, res) => { * content: * application/json: * schema: - * $ref: 'models/user' + * $ref: '#/components/schemas/User' * 401: * description: Invalid username or password */ diff --git a/server/src/server.js b/server/src/server.js index cd06d1e..6b53d3e 100644 --- a/server/src/server.js +++ b/server/src/server.js @@ -1,39 +1,16 @@ const express = require("express"); const bodyParser = require("body-parser"); const routes = require("./routes"); -const swaggerUi = require("swagger-ui-express"); -const swaggerJsdoc = require("swagger-jsdoc"); +const setupSwagger = require("./swagger"); const app = express(); app.use(bodyParser.json()); app.use("/api", routes); -const options = { - swaggerDefinition: { - openapi: "3.0.0", - info: { - title: "Campus Events and Entertainment Center API", - version: "1.0.0", - description: "API for managing campus events and entertainment", - }, - servers: [ - { - url: "http://localhost:5000/api", - }, - ], - }, - apis: ["./src/routes/*.js"], -}; +setupSwagger(app); -const specs = swaggerJsdoc(options); - -app.use( - "/api-docs", - swaggerUi.serve, - swaggerUi.setup(specs, { explorer: true }) -); app.use(express.json()); app.listen(5000, () => { console.log("Server is running on port 5000"); -}); +}); \ No newline at end of file diff --git a/server/src/swagger.js b/server/src/swagger.js new file mode 100644 index 0000000..d4bbb8e --- /dev/null +++ b/server/src/swagger.js @@ -0,0 +1,42 @@ +const fs = require("fs"); +const swaggerUi = require("swagger-ui-express"); +const swaggerJsdoc = require("swagger-jsdoc"); +const yaml = require("js-yaml"); + +const options = { + swaggerDefinition: { + openapi: "3.0.0", + info: { + title: "Campus Events and Entertainment Center API", + version: "1.0.0", + description: "API for managing campus events and entertainment", + }, + servers: [ + { + url: "http://localhost:5000/api", + }, + ], + }, + apis: ["./src/routes/*.js", "./src/models/*.js"], + failOnErrors: true, +}; + +const specs = swaggerJsdoc(options); + +const yamlString = yaml.dump(specs); + +fs.writeFile("swagger-auto-generated.yaml", yamlString, (err) => { + if (err) { + console.log(err); + } else { + console.log("YAML file has been saved."); + } +}); + +module.exports = (app) => { + app.use( + "/api-docs", + swaggerUi.serve, + swaggerUi.setup(specs, { explorer: true }) + ); +}; diff --git a/server/swagger-auto-generated.yaml b/server/swagger-auto-generated.yaml new file mode 100644 index 0000000..c16c7ac --- /dev/null +++ b/server/swagger-auto-generated.yaml @@ -0,0 +1,77 @@ +openapi: 3.0.0 +info: + title: Campus Events and Entertainment Center API + version: 1.0.0 + description: API for managing campus events and entertainment +servers: + - url: http://localhost:5000/api +paths: + /users/register: + post: + summary: Register a user + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - username + - password + properties: + username: + type: string + password: + type: string + responses: + '200': + description: User created successfully + /users/login: + post: + summary: Login a user + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - username + - password + properties: + username: + type: string + password: + type: string + responses: + '200': + description: User logged in successfully + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '401': + description: Invalid username or password +components: + schemas: + User: + type: object + required: + - username + - password + properties: + id: + type: integer + description: The auto-generated id of the user + readOnly: true + username: + type: string + description: The username of the user + password: + type: string + description: The password of the user + example: + id: 1 + username: user1 + password: pass1 +tags: [] diff --git a/server/swagger.yaml b/server/swagger.yaml new file mode 100644 index 0000000..c16c7ac --- /dev/null +++ b/server/swagger.yaml @@ -0,0 +1,77 @@ +openapi: 3.0.0 +info: + title: Campus Events and Entertainment Center API + version: 1.0.0 + description: API for managing campus events and entertainment +servers: + - url: http://localhost:5000/api +paths: + /users/register: + post: + summary: Register a user + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - username + - password + properties: + username: + type: string + password: + type: string + responses: + '200': + description: User created successfully + /users/login: + post: + summary: Login a user + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - username + - password + properties: + username: + type: string + password: + type: string + responses: + '200': + description: User logged in successfully + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '401': + description: Invalid username or password +components: + schemas: + User: + type: object + required: + - username + - password + properties: + id: + type: integer + description: The auto-generated id of the user + readOnly: true + username: + type: string + description: The username of the user + password: + type: string + description: The password of the user + example: + id: 1 + username: user1 + password: pass1 +tags: []