<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] >[success] # 初始化并且開發路由 * **初始化路由** :根據之前的 [技術方案](http://www.hmoore.net/wangjiachong/nodejs/2649930) 的設計,做出路由 * **返回假數據**: **將路由和假數據處理分離**,以符合設計原則 * **這里有2個問題** : 1. **什么是路由?路由其實就是接口** , 下面斜線后面的都算是 **路由(接口)** ![](https://img.kancloud.cn/64/6e/646e4e5eac77c8af835f7a91b760843e_573x235.png) 2. **為什么要返回假數據呢?** 因為 **目前還沒有學到數據庫,這是一個循循漸進的過程** ,暫時先使用返回假數據,后期學完數據庫后把假數據替換成真數據。 >[success] ## 初始化路由 ![](https://img.kancloud.cn/64/fc/64fc7bd1fa6f92a43c3dd4cebccd7a51_978x264.png) 之前在 **項目需求分析** 時候,我們就了解到接口需要這么多,總共分為 **2 個類型** ,一個是 **blog 博客類型** ,一個是 **user 類型** ,所以我們要通過 **2 個文件(模塊)** 來實現這 **6** 個接口(**blog 博客類型 5個接口** ,**user 類型 1個接口**),接下來我們在項目文件夾中創建一個 **src** 文件夾,然后在 **src** 下創建 **router 文件夾**,然后在 **router 文件夾** 中創建 **blog.js** 與 **user.js** **文件目錄結構**: ~~~ blog-1 // 項目文件夾 |__ bin // 可執行文件文件夾 | |__ www.js // 項目啟動入口文件 |__ src // 放接口的文件夾 | |__ router // 路由(接口)文件夾 | |__ blog.js // 【博客類型】有關的接口都寫在這里 | |__ user.js // 【用戶類型】有關的接口都寫在這里 | |__ app.js // 處理server業務邏輯的方法的文件 |__ package.json // 初始化項目文件 ~~~ **src/router/blog.js**: ~~~ const handleBlogRouter = (req, res) => { const method = req.method // GET POST // 獲取博客列表 if(method === 'GET' && req.path === '/api/blog/list'){ return { msg: '這是獲取博客列表的接口' // 后期從數據庫中取數據返回給前端 } } // 獲取博客詳情 if(method === 'GET' && req.path === '/api/blog/detail'){ return { msg: '這是獲取博客詳情的接口' } } // 新建一篇博客 if(method === 'POST' && req.path === '/api/blog/new'){ return { msg: '這是新建博客的接口' } } // 更新一篇博客 if(method === 'POST' && req.path === '/api/blog/update'){ return { msg: '這是更新博客的接口' } } // 刪除一篇博客 if(method === 'POST' && req.path === '/api/blog/delete'){ return { msg: '這是刪除博客的接口' } } } module.exports = handleBlogRouter ~~~ **src/router/user.js**: ~~~ const handleUserRouter = (req, res) => { const method = req.method // GET POST // 登陸 if(method === 'POST' && req.path === '/api/user/login'){ return { msg: '這是登陸博客的接口' } } } module.exports = handleUserRouter ~~~ 然后在 **app.js** 中引入這兩個方法,雖然目前在 **app.js** 中 **處理 blog 與 user 路由** 這種每次都需要判斷的方法不是非常的正規,會覺得非常的繁瑣,這就是 **原生 nodejs 不使用任何框架** 開發的不好處,后期用 **express** 或者 **Koa2** 開發時候就好了,先忍耐一下。 **app.js** : ~~~ // 引入處理路由文件 const handleBlogRouter = require('./src/router/blog') const handleUserRouter = require('./src/router/user') const serverHandle = (req, res) => { // 設置返回格式 JSON res.setHeader('Content-type', 'application/json') // 獲取 path const url = req.url req.path = url.split('?')[0] // 處理 blog 路由 const blogData = handleBlogRouter(req, res) if(blogData){ res.end( JSON.stringify(blogData) ) return // 這里需要return,不然返回數據后還會往下走 } // 處理 user 路由 const userData = handleUserRouter(req, res) if(userData){ res.end( JSON.stringify(userData) ) return } // 未命中路由,返回 404 res.writeHead(404, {"Content-type": "text/plain"}) // 把響應頭狀態碼設置為404,然后Content-type: text/plain是純文本,為了覆蓋上面的json類型 // 返回內容 res.write('404 Not Found\n') res.end() } module.exports = serverHandle ~~~ 此時就可以測試一下是否好用了,試一下訪問詳情接口, `http://127.0.0.1:8000/api/blog/detail` ![](https://img.kancloud.cn/d9/ca/d9cacbfeeadc0a3ecb138ae9ef691397_434x135.png) 接下來訪問一下 **404 頁面** ,直接瀏覽器輸入 `http://127.0.0.1:8000` ![](https://img.kancloud.cn/5d/1c/5d1c121041c37bd4c7b4d861364db0c6_383x153.png) 可以看到進入了 **404 頁面** ,這樣我們的初步就算完成了。 >[success] ## 開發路由 在開發路由之前,我們先創建一個 **數據模型** ,什么是 **數據模型** ? **數據模型:就是用來描述數據、組織數據和對數據進行操作** ,然后 **通過一個方法或者一個類返回一個我們想要的一個數據格式,可以理解成就是一個方法可以返回我們想要的數據結構**,例如:**下面代碼塊中,假如 data 是我們從數據庫中查出來的數據,我們把查出來的數據通過這個數據模型的方法處理之后,就會返回一個既有 data 也有 errno 字段的固定數據結構的對象** 。 **成功時返回的數據結構** ~~~ { data: [...] errno: 0, message: "獲取成功" } ~~~ **失敗時返回的數據結構** ~~~ { errno: -1 message: "獲取失敗,系統錯誤" } ~~~ 這樣前端就可以很方便的通過 **errno** 屬性來判斷獲取數據是成功還是失敗, **成功了就展示數據,錯誤了就提示 massage 中的錯誤提示**。 >[success] ### 創建數據模型 接下來 **創建** 一個 **存放數據模型代碼的文件夾和文件** ,在原有項目中 **src文件夾** 下 **創建 model 文件夾 和 resModel.js 文件** **文件目錄結構**: ~~~ blog-1 // 項目文件夾 |__ bin // 可執行文件文件夾 | |__ www.js // 項目啟動入口文件 | |__ src // 放接口的文件夾 | |__ router // 路由(接口)文件夾 | | |__ blog.js // 【博客類型】有關的接口都寫在這里 | | |__ user.js // 【用戶類型】有關的接口都寫在這里 | | | |__ model // 【存放數據模型】的文件夾 | |__ resModel.js // 【數據模型類】文件 | |__ app.js // 處理server業務邏輯的方法的文件 |__ package.json // 初始化項目文件 ~~~ **src/model/resModel.js** ~~~ // 基類 class BaseModel { constructor(data, message) { if(typeof data === 'string'){ // 這里是做一個兼容 this.message = data data = null message = null } if(data){ this.data = data } if(message){ this.message =message } } } // 成功返回時使用的數據模型類 class SuccessModel extends BaseModel { constructor(data, message){ super(data, message) // 執行一遍父類的內容 this.errno = 0 } } // 失敗返回時使用的數據模型類 class ErrorModel extends BaseModel { constructor(data, message){ super(data, message) // 執行一遍父類的內容 this.errno = -1 } } module.exports = { SuccessModel, ErrorModel } ~~~ >[success] ### 使用數據模型 **數據模型** 是在給前端返回數據時才會用到,想返回數據就需要先根據請求參數去數據庫取數據,所以我們先著手接口,接口在使用時候 **需要解析參數** ,我們之前寫的 **app.js** 中還沒有解析 **query 參數 與 post data 參數** ,首先我們需要改一下 **app.js** 1. **解析 query 參數** 跟 **post data 參數** **app.js** ~~~ const querystring = require('querystring') // 引入處理路由文件 const handleBlogRouter = require('./src/router/blog') const handleUserRouter = require('./src/router/user') // 用于處理 post data const getPostData = (req) => { const promise = new Promise((resolve, reject) => { if(req.method !== 'POST'){ // 不等于 post 請求 resolve({}) return } if(req.headers['content-type'] !== 'application/json'){ // 傳入的數據格式不是 application/json ,可能是form-data的參數 resolve({}) return } // 1. POST通過數據流方式接收數據 let postData = '' // 2. 給req注冊data事件,當有數據提交過來就會觸發,事件的作用是接收數據,接收大量數據的時候,是分塊接收的 req.on('data', chunk => { postData += chunk.toString() }) // 3. 給req注冊end事件,當數據全部接收完畢,會觸發 req.on('end', () => { if(!postData){ // 無數據返回空對象 resolve({}) return } resolve( JSON.parse(postData) ) }) }) return promise } const serverHandle = (req, res) => { // 設置返回格式 JSON res.setHeader('Content-type', 'application/json') // 獲取 path const url = req.url req.path = url.split('?')[0] // 解析query 參數 req.query = querystring.parse(url.split('?')[1]) // 處理 post data 參數 getPostData(req).then(postData => { req.body = postData // 處理 blog 路由 const blogData = handleBlogRouter(req, res) if(blogData){ res.end( JSON.stringify(blogData) ) return // 這里需要return,不然返回數據后還會往下走 } // 處理 user 路由 const userData = handleUserRouter(req, res) if(userData){ res.end( JSON.stringify(userData) ) return } // 未命中路由,返回 404 res.writeHead(404, {"Content-type": "text/plain"}) // 把響應頭狀態碼設置為404,然后Content-type: text/plain是純文本,為了覆蓋上面的json類型 // 返回內容 res.write('404 Not Found\n') res.end() }) } module.exports = serverHandle ~~~ 解析完了 **query 與 post data 參數** ,來看下圖,我們 **處理 router 文件夾中的路由接口的文件** 中返回的數據都是當初寫死的,要獲取數據還是要從數據庫中獲取,但是 **直接在這個文件中寫獲取數據的處理數據邏輯會很混亂** ,這時候,就要 **分出來一個 controller 文件來專門處理數據** ![](https://img.kancloud.cn/9d/79/9d79db1defdced9ad29ba009a8458147_798x286.png) 所以我們新建一個 **controller 文件夾** ,然后在里面創建 **blog.js** 和 **user.js** 文件 ~~~ blog-1 // 項目文件夾 |__ bin // 可執行文件文件夾 | |__ www.js // 項目啟動入口文件 | |__ src // 放接口的文件夾 | |__ router // 路由(接口)文件夾 | | |__ blog.js // 【博客類型】有關的接口都寫在這里 | | |__ user.js // 【用戶類型】有關的接口都寫在這里 | | | |__ model // 【存放數據模型】的文件夾 | | |__ resModel.js // 【數據模型類】文件 | | | |__ controller // 【從數據庫取出數據,然后處理數據,返回給路由層】 | |__ blog.js // 【博客類型】處理數據的文件 | |__ user.js // 【用戶類型】處理數據的文件 | |__ app.js // 處理server業務邏輯的方法的文件 |__ package.json // 初始化項目文件 ~~~ 然后在 **controller 中的 blog.js 與 user.js文件** 中進行 **從數據庫(controller 這里先假裝使用數據庫查詢出來的數據)獲取數據的操作,以及處理數據的邏輯,處理完成后再返回給對應路由的方法中** **src/controller/blog.js** ~~~ /** * 獲取博客列表 * @param {string} author - 作者 * @param {string} keyword - 搜索關鍵字 */ const getList = (author, keyword) => { // 先返回假數據(格式是正確的) // author, keyword這2個參數等開始學習數據庫查詢時候會用到,目前先假裝已經使用了author, keyword 屬性查出來的下列數據。 return [ { id: 1, title: '標題A', content: '內容A', createTime: '1645696670000', author: 'zhangsan' }, { id: 2, title: '標題B', content: '內容B', createTime: '1645696790000', author: 'lisi' } ] } /** * 獲取博客詳情 * @param {number} id - 博客列表 item id */ const getDetail = (id) => { return { id: 1, title: '標題A', content: '內容A', createTime: '1645696670000', author: 'zhangsan' } } /** * 新增博客 * @param {object} blogData - blogData 是一個博客對象,包含 title content author 屬性 */ const newBlog = (blogData = {}) => { // 這里假裝已經向數據庫進行了新增操作 return { id: 3 // 表示新建博客,插入到數據表里面的id } } /** * 更新博客 * @param {number} id - 要更新的博客的id * @param {object} blogData - blogData 是一個博客對象,包含 title content 屬性 */ const updateBlog = (id, blogData = {}) => { // 這里假裝已經向數據庫進行了更新操作 return true } /** * 刪除博客 * @param {number} id - 要刪除的博客的id * @param {string} author - 作者身份,因為不可以越權刪除,所以要加作者 */ const deleteBlog = (id) => { // 這里假裝已經向數據庫進行了刪除操作 return true } module.exports = { getList, getDetail, newBlog, updateBlog, deleteBlog } ~~~ **src/controller/user.js** ~~~ /** * 登陸 * @param {string} username - 用戶名 * @param {string} password - 密碼 */ const login = (username, password) => { // 先使用假數據 if(username === 'zhangsan' && password === '123'){ return true } return false } module.exports = { login } ~~~ 2. 開始使用 **數據模型** 在 **blog 和 user** 這2個路由文件中使用數據模型 **SuccessModel** 和 **ErrorModel** 這2個類來處理數據格式 **src/router/blog.js** ~~~ // 從 controller 中獲取數據 const { getList, getDetail, newBlog, updateBlog, deleteBlog } = require('../controller/blog') // 引入數據模型 const { SuccessModel, ErrorModel } = require('../model/resModel') const handleBlogRouter = (req, res) => { const method = req.method // GET POST const id = req.query.id // 獲取博客列表 if(method === 'GET' && req.path === '/api/blog/list'){ // 取得參數 const author = req.query.author || '' const keyword = req.query.keyword || '' // 從 controller 中獲取數據 const listData = getList(author, keyword) // 通過數據模型加工數據返回帶有 erron 屬性的對象數據 return new SuccessModel(listData) } // 獲取博客詳情 if(method === 'GET' && req.path === '/api/blog/detail'){ const data = getDetail(id) return new SuccessModel(data) } // 新建一篇博客 if(method === 'POST' && req.path === '/api/blog/new'){ const data = newBlog(req.body) return new SuccessModel(data) } // 更新一篇博客 if(method === 'POST' && req.path === '/api/blog/update'){ const result = updateBlog(id, req.body) if(result){ // 更新成功 return new SuccessModel() } else { return new ErrorModel('更新博客失敗') } } // 刪除一篇博客 if(method === 'POST' && req.path === '/api/blog/delete'){ const result = deleteBlog(id) if(result){ // 刪除成功 return new SuccessModel() } else { return new ErrorModel('刪除博客失敗') } } } module.exports = handleBlogRouter ~~~ **src/router/user.js** ~~~ // 從 controller 中獲取數據 const { login } = require('../controller/user') // 引入數據模型 const { SuccessModel, ErrorModel } = require('../model/resModel') const handleUserRouter = (req, res) => { const method = req.method // GET POST // 登陸 if(method === 'POST' && req.path === '/api/user/login'){ const { username, password } = req.body const result = login(username, password) if(result){ // 登陸成功 return new SuccessModel() } else { return new ErrorModel('登陸失敗') } } } module.exports = handleUserRouter ~~~ >[success] ## 總結 我們目前分了 **4 層結構, 每層都有自己的職責劃分,處理每層的事務** 1. **www.js** 都是一些 **createServer** 邏輯 2. **app.js** 是系統基本設置的一個文件,例如:**設置數據返回類型 、獲取path、解析query、處理路由、處理未命中 404** 3. **router 里面只管路由,返回給正確的格式數據,至于數據返回的是什么、如何計算的、怎么篩選的它不管,它只關心和路由有關的事情,具體的數據,怎么摘出來,怎么篩選出來,數據是正確還是錯誤的它都不管** 4. **controller 層是最關心數據的一層,在 controller 中會進行數據庫的查詢以及對數據的計算和篩選等處理** 我們接收到一個請求后會按照這個流程 **www.js 》app.js 》router路由 》controller** 來走,從 **www.js 一步步到 controller**,再從 **controller** 取到數據后層層向上傳遞直到傳到 **www.js** ,再通過 **www.js** 的 **res.end** 方法將數據返回給瀏覽器客戶端,這一切就仿佛在畫一個圓圈一樣,**從起點畫到終點,再從終點往回畫到起點**。 ![](https://img.kancloud.cn/3c/e0/3ce0afa6c83e2715e91f2669f866cd80_715x764.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看