Skip to content

Commit c836f33

Browse files
committed
Feature(mock): rewrite mock-server base on REST and Swagger
* Use faker instead of mock.js * Use express server to host the fake data * Support swagger config file * Based on REST api
1 parent dbaa022 commit c836f33

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2182
-862
lines changed

.env.production

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
# Base api
2-
VUE_APP_BASE_API = '/prod-api'
2+
# Remeber to change this to your production server address
3+
# Here I used my mock server for this project
4+
VUE_APP_BASE_API = 'https://vue-typescript-admin-mock-server.armour.now.sh/mock-api/v1/'

mock/api.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './articles'
2+
export * from './role'
3+
export * from './transactions'
4+
export * from './users'

mock/article.ts

-116
This file was deleted.

mock/articles.ts

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import faker from 'faker'
2+
import { Response, Request } from 'express'
3+
import { IArticleData } from '../src/api/types'
4+
5+
const articleList: IArticleData[] = []
6+
const articleCount = 100
7+
const mockFullContent = '<p>I am testing data, I am testing data.</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>'
8+
9+
for (let i = 0; i < articleCount; i++) {
10+
articleList.push({
11+
id: i,
12+
status: faker.random.arrayElement(['published', 'draft', 'deleted']),
13+
title: faker.lorem.sentence(6, 10),
14+
abstractContent: faker.lorem.sentences(2),
15+
fullContent: mockFullContent,
16+
sourceURL: faker.internet.url(),
17+
imageURL: faker.image.imageUrl(),
18+
timestamp: faker.date.past().getTime(),
19+
platforms: [faker.random.arrayElement(['a-platform', 'b-platform', 'c-platform'])],
20+
disableComment: faker.random.boolean(),
21+
importance: faker.random.number({ min: 1, max: 3}),
22+
author: faker.name.findName(),
23+
reviewer: faker.name.findName(),
24+
type: faker.random.arrayElement(['CN', 'US', 'JP', 'EU']),
25+
pageviews: faker.random.number({ min: 300, max: 500 })
26+
})
27+
}
28+
29+
export const getArticles = (req: Request, res: Response) => {
30+
const { importance, type, title, page = 1, limit = 20, sort } = req.query
31+
32+
let mockList = articleList.filter(item => {
33+
if (importance && item.importance !== +importance) return false
34+
if (type && item.type !== type) return false
35+
if (title && item.title.indexOf(title) < 0) return false
36+
return true
37+
})
38+
39+
if (sort === '-id') {
40+
mockList = mockList.reverse()
41+
}
42+
43+
const pageList = mockList.filter((_, index) => index < limit * page && index >= limit * (page - 1))
44+
45+
return res.json({
46+
code: 20000,
47+
data: {
48+
total: mockList.length,
49+
items: pageList
50+
}
51+
})
52+
}
53+
54+
export const getArticle = (req: Request, res: Response) => {
55+
const { id } = req.params
56+
for (const article of articleList) {
57+
if (article.id.toString() === id) {
58+
return res.json({
59+
code: 20000,
60+
data: article
61+
})
62+
}
63+
}
64+
return res.json({
65+
code: 70001,
66+
message: 'Article not found'
67+
})
68+
}
69+
70+
export const createArticle = (req: Request, res: Response) => {
71+
const { data } = req.body
72+
return res.json({
73+
code: 20000,
74+
data
75+
})
76+
}
77+
78+
export const updateArticle = (req: Request, res: Response) => {
79+
const { id } = req.params
80+
const { data } = req.body
81+
for (const article of articleList) {
82+
if (article.id.toString() === id) {
83+
return res.json({
84+
code: 20000,
85+
data
86+
})
87+
}
88+
}
89+
return res.json({
90+
code: 70001,
91+
message: 'Article not found'
92+
})
93+
}
94+
95+
export const deleteArticle = (req: Request, res: Response) => {
96+
return res.json({
97+
code: 20000,
98+
})
99+
}
100+
101+
export const getPageviews = (req: Request, res: Response) => {
102+
return res.json({
103+
code: 20000,
104+
data: {
105+
pageviews: [
106+
{ key: 'PC', pageviews: 1024 },
107+
{ key: 'Mobile', pageviews: 1024 },
108+
{ key: 'iOS', pageviews: 1024 },
109+
{ key: 'Android', pageviews: 1024 }
110+
]
111+
}
112+
})
113+
}

mock/index.ts

-69
This file was deleted.

mock/mock-server.ts

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import express from 'express'
2+
import bodyParser from 'body-parser'
3+
import compression from 'compression'
4+
import morgan from 'morgan'
5+
import cors from 'cors'
6+
import http from 'http'
7+
import path from 'path'
8+
import yaml from 'yamljs'
9+
import * as api from './api'
10+
import { accessTokenAuth } from './security'
11+
12+
const app = express()
13+
const port = 9528
14+
const { connector, summarise } = require('swagger-routes-express')
15+
16+
// Compression
17+
app.use(compression())
18+
// Logger
19+
app.use(morgan('dev'))
20+
// Enable CORS
21+
app.use(cors())
22+
// POST, PUT, DELETE body parser
23+
app.use(bodyParser.json({ limit: '20mb' }))
24+
app.use(bodyParser.urlencoded({
25+
limit: '20mb',
26+
extended: false
27+
}))
28+
// No cache
29+
app.use((req, res, next) => {
30+
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate')
31+
res.header('Pragma', 'no-cache')
32+
res.header('Expires', '-1')
33+
next()
34+
})
35+
36+
// Read and swagger config file
37+
const apiDefinition = yaml.load(path.resolve(__dirname, 'swagger.yml'))
38+
// Create mock functions based on swaggerConfig
39+
const options = {
40+
security: {
41+
AccessTokenAuth: accessTokenAuth
42+
}
43+
}
44+
const connectSwagger = connector(api, apiDefinition, options)
45+
connectSwagger(app)
46+
// Print swagger router api summary
47+
const apiSummary = summarise(apiDefinition)
48+
console.log(apiSummary)
49+
50+
// Catch 404 error
51+
app.use((req, res, next) => {
52+
const err = new Error('Not Found')
53+
res.status(404).json({
54+
message: err.message,
55+
error: err
56+
})
57+
})
58+
59+
// Create HTTP server.
60+
const server = http.createServer(app)
61+
62+
// Listen on provided port, on all network interfaces.
63+
server.listen(port)
64+
server.on('error', onError)
65+
console.log('Mock server started on port ' + port + '!')
66+
67+
// Event listener for HTTP server "error" event.
68+
function onError(error: any) {
69+
if (error.syscall !== 'listen') {
70+
throw error
71+
}
72+
const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port
73+
// handle specific listen errors with friendly messages
74+
switch (error.code) {
75+
case 'EACCES':
76+
console.error('Express ERROR (app) : %s requires elevated privileges', bind)
77+
process.exit(1)
78+
case 'EADDRINUSE':
79+
console.error('Express ERROR (app) : %s is already in use', bind)
80+
process.exit(1)
81+
default:
82+
throw error
83+
}
84+
}

0 commit comments

Comments
 (0)