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

我曾寫過兩篇文章:jQuery進階:用最優雅的方式寫ajax請求, axios進階:用最優雅的方式寫ajax請求, 原理都是在將使用配置文件的方式,自動生成接口方法。 在多個項目中,我曾使用這種配置的方式批量生成ajax接口,可是每次都要造輪子是很繁瑣的,索性本身發佈一個npm包吧,因而xfire出來了。html

將配置數據從代碼中分離出來 -- 《編寫可維護的JavaScript》--Nicholas C. Zakas,我是看了這本書,才激發出用配置文件生成各類接口的想法。ios

xfire地址:點擊到達git

以爲不錯的話,能夠給xfire點個贊或者開個issue,或者提個建議。謝謝。github

xfire

很是簡單,高度可配置的fetch接口批量生成工具。ajax


特色

  • 很是簡單: 提供配置文件,自動生成接口
  • 提早驗證:支持請求體格式驗證
  • 報錯詳細: 給出具體的報錯位置,字段信息

安裝

npm install -S xfire

yarn add xfire
複製代碼

demo

首先須要一個配置文件npm

// 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'
      }
    }
  ]
}
複製代碼

而後引入xfirejson

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

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

POTS 發送formData類型的數據示例axios

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

GET 數據示例segmentfault

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

POST json類型數據示例windows

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

只須要爲您的網站,爲每一個瀏覽器量身定製的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不支持之外,大部分經常使用瀏覽器都支持了。

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

相關文章
相關標籤/搜索