造輪子:用Node寫一個API Mock

使用Node寫一個Mock服務(wù)

實現(xiàn)思路:

  1. 讀取mock文件夾
  2. 遍歷.js文件
  3. 嘗試導(dǎo)入文件內(nèi)容
  4. 將文件內(nèi)容拼接成一個對象
  5. 請求類型 + 空格 + 請求地址作為key
  6. 當(dāng)收到的請求能在js對象中找到就返回結(jié)果
  7. 找不到結(jié)果返回404

獲取文件內(nèi)容

    // ./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')) {
                // 容錯,可能文件內(nèi)容有問題
                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;

實現(xiàn)解析

    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) => {
        // 對應(yīng)mock的請求類型 + 空格 + 請求地址的映射
        const request = `${ctx.method} ${ctx.path}`;
        // TODO 容錯
        try {
            const mock = mockBundle[request];
            const mockType = toString.call(mock);
            if (mockType === '[object Function]') { // mock數(shù)據(jù)為函數(shù)
                let query;
                if (ctx.method === 'GET') {
                    query = ctx.query;
                } else if (ctx.method === 'POST') {
                    query = ctx.request.body;
                }
                // 返回mock結(jié)果
                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函數(shù)執(zhí)行出錯'
            }
        }
        // 找不到mock函數(shù),那么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('系統(tǒng)錯誤', err)
    });

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

源碼地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容