造輪子:用Node寫一個API Mock

使用Node寫一個Mock服務

實現思路:html

  1. 讀取mock文件夾
  2. 遍歷.js文件
  3. 嘗試導入文件內容
  4. 將文件內容拼接成一個對象
  5. 請求類型 + 空格 + 請求地址做爲key
  6. 當收到的請求能在js對象中找到就返回結果
  7. 找不到結果返回404

獲取文件內容

// ./src/utils/getMock.js

    const fs = require('fs');
    const path = require('path');

    const getMockBundleOfDir = (mockDirPath) => {
        // 同步讀取mock文件夾 
        const fileNameList = fs.readdirSync(mockDirPath);
        // mock對象彙總
        let mockBundle = {};
        // 遍歷文件
        fileNameList.forEach(fileName => {
            const filePtah = path.resolve(`${mockDirPath}/${fileName}`);
            // 只讀取JS文件
            if (fileName.endsWith('.js')) {
                // 容錯,可能文件內容有問題
                try {
                    const content = require(filePtah);
                    // 只合並對象
                    if (Object.prototype.toString.call(content) === '[object Object]') {
                        Object.assign(mockBundle, content);
                    }
                } catch (error) {
                    console.log('\033[41;37m', `讀取${filePtah}文件出錯`, '\033[0m');
                }
            }
        })
        return mockBundle;
    }

    module.exports = getMockBundleOfDir;
複製代碼

實現解析

const Koa = require('koa');
    const koaBody = require('koa-body');
    const loggerAsync = require('./src/middle/log.js');
    const getMockBundleOfDir = require('./src/utils/getMock.js');

    const toString = Object.prototype.toString;
    const mockDirPath = './src/mock'; // mock目錄地址

    // 獲取mock對象集合
    let mockBundle = getMockBundleOfDir(mockDirPath);

    const app = new Koa();
    app.use(koaBody()); // koa插件,用來解析post請求的body

    // mock請求
    app.use(async (ctx, next) => {
        // 對應mock的請求類型 + 空格 + 請求地址的映射
        const request = `${ctx.method} ${ctx.path}`;
        // TODO 容錯
        try {
            const mock = mockBundle[request];
            const mockType = toString.call(mock);
            if (mockType === '[object Function]') { // mock數據爲函數
                let query;
                if (ctx.method === 'GET') {
                    query = ctx.query;
                } else if (ctx.method === 'POST') {
                    query = ctx.request.body;
                }
                // 返回mock結果
                const response = mock(query);
                return ctx.body = response;
            } else if (mock) { // 有值
                return ctx.body = mock;
            }
        } catch (error) {
            ctx.status = 500;
            return ctx.body = {
                error,
                msg: 'mock函數執行出錯'
            }
        }
        // 找不到mock函數,那麼next
        next();
    })


    // 底線
    app.use(async ctx => {
        let html = `
            <h1>404</h1>
            <h2>請確認URL是否正確、請求類型是否大寫</h2>
        `;
        ctx.status = 404;
        ctx.body = html
    })

    app.on('error', err => {
        console.error('系統錯誤', err)
    });

    app.listen(3333, () => {
        // console.log(process.argv, 'argv')
        console.log('\033[44;37m > 開始運行 ', '端口3333', '\033[0m');
    });

複製代碼

源碼地址

相關文章
相關標籤/搜索