xfire: 簡單優雅、高度可配置的fetch(ajax) 介面批量生成工具

香吉士發表於2018-01-15

我曾寫過兩篇文章:jQuery進階:用最優雅的方式寫ajax請求, axios進階:用最優雅的方式寫ajax請求, 原理都是在將使用配置檔案的方式,自動生成介面方法。 在多個專案中,我曾使用這種配置的方式批量生成ajax介面,但是每次都要造輪子是很繁瑣的,索性自己釋出一個npm包吧,於是xfire出來了。

將配置資料從程式碼中分離出來 -- 《編寫可維護的JavaScript》--Nicholas C. Zakas,我是看了這本書,才激發出用配置檔案生成各種介面的想法。

xfire地址:點選到達

覺得不錯的話,可以給xfire點個贊或者開個issue,或者提個建議。謝謝。

xfire

非常簡單,高度可配置的fetch介面批量生成工具。


特點

  • 非常簡單: 提供配置檔案,自動生成介面
  • 提前驗證:支援請求體格式驗證
  • 報錯詳細: 給出具體的報錯位置,欄位資訊

安裝

npm install -S xfire

yarn add xfire
複製程式碼

demo

首先需要一個配置檔案

// api.config.js

export default {
  prefix: 'http://localhost:80',
  list: [
    {
      name: 'login',
      desp: 'sercurity login',
      path: '/agent/login',
      method: 'post',
      contentType: 'formData',
      bodyStruct: {
        username: 'string',
        password: 'string',
        namespace: 'string'
      },
      defaultBody: {
        password: 'Aa123456'
      },
      status: {
        401: 'username or password wrong'
      }
    },
    {
      name: 'heartBeat',
      path: '/sdk/api/csta/agent/heartbeat/{{agentId}}',
    },
    {
      name: 'setAgentState',
      desp: 'set agent state',
      path: '/sdk/api/csta/agent/state/{{namespace}}',
      method: 'post',
      bodyStruct: {
        agentId: 'string?',
        loginId: 'string',
        func: 'string',
        agentMode: 'string?',
        device: 'string?',
        password: 'string'
      }
    }
  ]
}
複製程式碼

然後引入xfire

import xfire from 'xfire'
import apiConfig from './api.config.js'

const API = xfire.init(apiConfig)
複製程式碼

POTS 傳送formData型別的資料示例

API.login.fire({}, {
  username: 'wangduanduan',
  password: '123456',
  namespace: 'dd.com'
})
.then((res) => {
  console.log(res)
})
.catch((err) => {
  console.log(err)
})
複製程式碼

GET 資料示例

API.heartBeat.fire({
  agentId: '5001@dd.com'
})
.then((res) => {
  console.log(res)
})
.catch((err) => {
  console.log(err)
})
複製程式碼

POST json型別資料示例

API.setAgentState.fire({
  namespace: 'windows'
}, {
  agentId: '5001@dd.com',
  loginId: '5001@dd.com',
  func: 'login',
  agentMode: 'Ready',
  device: '8001@dd.com',
  password: '123456'
})
.then((res) => {
  console.log(res)
})
.catch((err) => {
  console.log(err)
})
複製程式碼

xfire API

const API = xfire.init(config)
複製程式碼

config 欄位說明

注意:如果config無法通過下面的格式驗證,則會直接報錯

欄位名 型別 是否必須 預設值 說明
config.prefix string 介面url公用的字首
config.list array 介面陣列

config list欄位說明

欄位名 型別 是否必須 預設值 說明
name string 介面名
desp string 介面描述
path string 介面路徑
method enum string get 請求方式: get, post, put, delete
contentType enum string json 請求體型別: json, formData。json會被渲染: application/json; charset=UTF-8, formData會被渲染成: application/x-www-form-urlencoded; charset=UTF-8
bodyStruct object 請求體格式驗證結構, 如果bodyStruct存在,則使用bodyStruct驗證body: 具體格式參考superstruct
defaultBody object 預設請求體。bodyStruct存在的情況下才有效
status object 響應狀態碼及其含義

當某個list物件的 name 不存在時,config驗證時的報錯:

Uncaught StructError: Expected a value of type `string` for `name` but received `undefined`.
複製程式碼

當傳送請求時,請求體不符合bodyStruct時, 報錯如下

...
name: 'login',
desp: 'sercurity login',
path: '/agent/login',
method: 'post',
contentType: 'formData',
bodyStruct: {
  username: 'string',
  password: 'string',
  namespace: 'string'
},
...

API.login.fire({}, {
  // username: '5001',
  password: 'Aa123456',
  namespace: 'zhen04.cc'
})

Uncaught StructError: Expected a value of type `string` for `username` but received `undefined`.
複製程式碼

xfire 例項 API

xfire.init()方法會返回xfire例項物件,該物件上有一個特殊方法$setHeaders, 還有其他的由配置檔案產生的方法。

const API = xfire.init(apiConfig)
複製程式碼

$setHeaders(): 設定請求頭部資訊

$setHeaders()用來設定除了contentType以外的請求頭, 一旦設定請求頭部資訊,所有的例項介面在傳送請求時,都會帶有該頭部資訊。

API.$setHeaders({sessionId: 'jfsldkf-sdflskdjf-sflskfjlsf'})
複製程式碼

api方法: fire(pathParm, body)

pathParm物件上的資料最終會被渲染到請求路徑上, body是請求體。

...
    {
      name: 'heartBeat',
      desp: 'agent heart beat',
      path: '/sdk/api/csta/agent/heartbeat/{{agentId}}',
      method: 'post'
    },
...
複製程式碼

類似上面的物件,會產生一個以heartBeat為名稱的方法,所有請求方法都是fire()方法。

API.xxx.fire(pathParm, body)

// 不需要請求體時, body可以不傳
API.xxx.fire(pathParm)

// 不需要引數渲染到路徑時,pathParm必須傳空物件:{}
API.xxx.fire({}, body)
複製程式碼

例子:

API.heartBeat({
  agentId: '5001@ee.com'
})
.then((res) => {
  console.log(res)
})
.catch((err) => {
  console.log(err)
})
複製程式碼

關於path和 fire的 pathParm引數:

// path 如下
path: '/store/order/{{type}}/{{age}}'

// 則pathParm應該是
{
  type: 'dog',
  age: 14
}
複製程式碼

注意: pathParm不支援複雜的資料型別。

// 原始資料型別 string, number, boolean 都是可以的
{
  key1: 'string',
  key2: number,
  key3: boolean
}

// 複雜的資料型別,如陣列和巢狀物件, 函式, 將導致渲染失敗
// bad
{
  key1: [1, 3, 3],
  key2: {
    key3: 'string'
  },
  key4: function(){}
}
複製程式碼

polyfill

xfire底層使用了瀏覽器原生的Promise, fetch, Object.keys(), Object.assign() 所以對瀏覽器是有要求的。xfire本身不帶有任何polyfill。

目前IE11以及以下是不支援Promise和fetch的。

在此給出兩個方案:

方案1: babel-polyfill

通過引入babel-polyfill, 讓瀏覽器支援xfire所需要的原生方法。

方案2: polyfill.io

xfire:  簡單優雅、高度可配置的fetch(ajax) 介面批量生成工具

只需要為您的網站,為每個瀏覽器量身定製的polyfills。 複製程式碼釋放魔法:

<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
複製程式碼

Polyfill.io讀取每個請求的User-Agent頭並返回適合請求瀏覽器的polyfill。 根據您在應用中使用的功能量身定製響應,並檢視我們的例項以快速入門。

ajax Vs fetch

與其使用各種ajax第三方庫,不如使用原始fetch。ajax是過去,fetch是現在和將來。

總結一下,Fetch 優點主要有:

語法簡潔,更加語義化 基於標準 Promise 實現,支援 async/await 同構方便,使用 isomorphic-fetch --傳統 Ajax 已死,Fetch 永生 未來更容易擴充套件 -- by me

我使用ajax經歷過三個階段:

  1. jQuery時期,我用jQuery的ajax
  2. 類似Vue的現代框架時,使用axio
  3. 再後來我就使用瀏覽器原生的fetch

Fetch API 提供了一個 JavaScript介面,用於訪問和操縱HTTP管道的部分,例如請求和響應。它還提供了一個全域性 fetch()方法,該方法提供了一種簡單,合乎邏輯的方式來跨網路非同步獲取資源。-- MDN

這種功能以前是使用 XMLHttpRequest實現的。Fetch提供了一個更好的替代方法,可以很容易地被其他技術使用,例如 Service Workers。Fetch還提供了單個邏輯位置來定義其他HTTP相關概念,例如 CORS和HTTP的擴充套件。-- MDN

caniuse的資料來看,fetch方法除IE11不支援以外,大部分常用瀏覽器都支援了。

xfire:  簡單優雅、高度可配置的fetch(ajax) 介面批量生成工具

fetch介面示例:

fetch('/users.json')
  .then(function(response) {
    return response.json()
  }).then(function(json) {
    console.log('parsed json', json)
  }).catch(function(ex) {
    console.log('parsing failed', ex)
  })


  fetch('/users.html')
  .then(function(response) {
    return response.text()
  }).then(function(body) {
    document.body.innerHTML = body
  })
複製程式碼

fetch相關文章

fetch相關庫

進階書籍

ie 8/9/10 早已被微軟放棄

微軟公司正式宣佈:從當地時間2016年1月12日,停止對IE 8/9/10三個版本的技術支援,相應的使用者將不會再收到任何來自微軟官方的IE安全更新。-- Support for older versions of Internet Explorer ended

xfire:  簡單優雅、高度可配置的fetch(ajax) 介面批量生成工具

xfire:  簡單優雅、高度可配置的fetch(ajax) 介面批量生成工具

相關文章