這篇裏是如何定義接口,咱們通常訪問接口如:post請求調用http://127.0.0.1:11000/webapi/userinfo/user 這個接口,成功返回用戶信息,若是失敗要返回失敗緣由等。javascript
首先分析一下 /webapi/userinfo/login 接口。從這裏能夠看出 webapi是一個類,userinfo也是一個類,user是一個方法。再接合post、delete、put、get請求能夠獲得四個方法了,這樣就能夠實現增、刪、改、查的功能。css
接下咱們就先建立一個webapi.js文件,裏面的內容以下java
const UserInfo = require('./UserInfo');
module.exports = {
userinfo: new UserInfo(),
};
再就是建立UserInfo.js,裏面的內容:git
/** * 用戶信息類 * * @class UserInfo */
class UserInfo {
constructor(DbHelper, Utility) {
this.DbHelper = DbHelper;
this.Utility = Utility;
}
post_login(request, response, options) {
}
get_user(request, response, options) {
response.Send({ msg: '這是一個get請求', options });
}
post_user(request, response, options) {
response.Send({ msg: '這是一個 post 請求', options });
}
delete_user(request, response, options) {
response.Send({ msg: '這是一個 delete 請求', options });
}
put_user(request, response, options) {
response.Send({ msg: '這是一個 put 請求', options });
}
}
module.exports = UserInfo;
光這樣寫仍是不行的啦,還要修改在上上篇中router裏的代碼,要不是調用不了接口的。
咱們得還要建一個 index.js文件github
// 這個是以前引用進來,這個就是/webapi部分
const webapi = require('./webapi');
// const order = require('./orderapi'); http://xxx/orderapi/list
// const car = require('./carapi'); http://xxx/car/goods
// const DealBusiness = require('./DealBusiness');
// ...
//
module.exports = {
webapi,
// order,car , DealBusiness: new DealBusiness() ,...
}
建立完這個文件好了後,在router裏從require(index.js)文件了。經過匹配url路徑中的匹配到定義好的接口。找了就調用相應的接口,沒有找到的就向返回400等信息
web
定好了,就能夠先用postman來試一下接口定義是否能夠用了。下圖是調用get請求的狀況。
數據庫
下面這張圖是調用post請求返回的信息
json
這樣接口調用基本就搞定啦。api
這裏完整把router.js裏router類在這裏放一下markdown
class routes {
constructor(req, res) {
this.ApiInfo = api;
this.res = res;
this.req = req;
}
initHeader() {
this.res.setHeader("Content-Type", "application/json;charset=utf-8");
this.res.setHeader("Access-Control-Allow-Origin", "*");
this.res.setHeader("access-control-allow-headers", "x-pingother, origin, x-requested-with, content-type, accept, xiaotuni,systemdate");
this.res.setHeader("access-control-allow-methods", "GET, POST, PUT, DELETE, OPTIONS");
this.res.setHeader("Access-Control-Expose-Headers", "date, token,systemdate");
this.res.setHeader('systemdate', new Date().getTime());
const { method } = this.req;
if (method && method === 'OPTIONS') {
this.res.end();
return;
}
this.processRequestMethod(method);
}
processRequestMethod(method) {
const PathInfo = path.parse(this.req.url);
if (!this.judgeIsCallApi(PathInfo)) {
return;
}
this.Method = method.toLocaleLowerCase();
this.parseUrlParams();
this.__ProcessApi(PathInfo);
}
__ProcessApi(PathInfo) {
const methodInfo = { pathname: this.UrlInfo.pathname, method: this.Method };
// 以utf-8的形式接受body數據
this.req.setEncoding('utf8');
let __ReData = "";
// 這裏接受用戶調用接口時,向body發送的數據
this.req.on('data', (data) => {
__ReData += data;
});
const __self = this;
this.req.on('end', () => { // 監聽數據接受完後事件。
// 查詢用戶定義好的接口。
const { func, ctrl } = __self.__FindMethod(PathInfo) || {};
const data = __ReData && __ReData !== '' ? JSON.parse(__ReData) : {};
if (func) {
func.apply(ctrl, [__self.req, __self.res, { params: __self.QueryParams, data }]);
return;
}
const _db = new DbHelper(); // 實例化一個數據庫操做類
__self.ApiInfo.DealBusiness.Process(_db, __self.req, __self.res, { methodInfo, params: __self.QueryParams, data });
});
}
judgeIsCallApi(PathInfo) {
if (PathInfo.ext === '') {
return true;
}
let charset = "binary";
switch (PathInfo.ext) {
case ".js":
this.res.writeHead(200, { "Content-Type": "text/javascript" });
break;
case ".css":
this.res.writeHead(200, { "Content-Type": "text/css" });
break;
case ".gif":
charset = "binary";
this.res.writeHead(200, { "Content-Type": "image/gif" });
break;
case ".jpg":
charset = "binary";
this.res.writeHead(200, { "Content-Type": "image/jpeg" });
break;
case ".png":
charset = "binary";
this.res.writeHead(200, { "Content-Type": "image/png" });
break;
default:
this.res.writeHead(200, { "Content-Type": "application/octet-stream" });
}
const { dir, ext, name } = PathInfo;
const __abs = path.join(dir, name + ext);
const _pathInfo = [path.join('./server/', __abs), path.join('.', __abs)];
const __self = this;
let __fileIsExist = false;
for (let i = 0; i < _pathInfo.length; i++) {
const dir = _pathInfo[i];
__fileIsExist = fs.existsSync(dir);
if (__fileIsExist) {
fs.readFile(dir, (err, data) => {
if (err) {
__self.res.Send({ code: -1, msg: err.toString() });
} else {
__self.res.write(data, charset);
}
__self.res.end();
});
return false;
}
}
if (!__fileIsExist) {
__self.res.end();
}
return false;
}
parseUrlParams() {
const _url = url.parse(this.req.url);
this.UrlInfo = _url;
const { query } = _url;
this.QueryParams = querystring.parse(query);
}
__FindMethod(PathInfo, isSendMsg) {
const { pathname } = this.UrlInfo;
const pathList = pathname.split('/');
pathList.shift();
if (pathList.length === 1) {
if (isSendMsg) {
this.res.Send_404({ status: 404, msg: pathname + '接口沒有找到' });
}
return null;
}
const __last = pathList.pop();
let __CallApi = this.ApiInfo[pathList[0]];
let __ApiIsExist = true;
for (let i = 1; i < pathList.length; i++) {
__CallApi = __CallApi[pathList[i]];
if (!__CallApi) {
__ApiIsExist = false;
break;
}
}
if (!__ApiIsExist) {
if (isSendMsg) {
this.res.Send_404({ status: 404, msg: pathname + '接口沒有找到' });
}
return null;
}
const Controller = __CallApi;
__CallApi = __CallApi[this.Method + '_' + __last]
if (!__CallApi) {
if (isSendMsg) {
this.res.Send_404({ status: 404, msg: pathname + '接口沒有找到' });
}
return null;
}
return { func: __CallApi, ctrl: Controller };
}
}
module.exports = routes ;
如今接口的調用基本就OK了。
若是有什麼不清楚,能夠查看 https://github.com/xiaotuni/angular-map-http2 這裏項目裏具體寫了怎麼實現接口調用的