Fast_Responder 快捷響應(yīng)服務(wù)
v1.0.0
簡(jiǎn)介
Fast_Responder是一個(gè)可以讓你快速創(chuàng)建Http請(qǐng)求應(yīng)答器(responder)的服務(wù)蘸炸。應(yīng)答器可以接收配置的任意請(qǐng)求路徑的請(qǐng)求,并按照你的配置對(duì)請(qǐng)求參數(shù)進(jìn)行判斷呆抑,以返回不同的結(jié)果。除了處理請(qǐng)求外,應(yīng)答器還可以對(duì)任意個(gè)請(qǐng)求地址按你配置的延遲時(shí)間显设,請(qǐng)求頭和參數(shù)發(fā)起Http請(qǐng)求僻澎。本質(zhì)上,fast_responder是一個(gè)動(dòng)態(tài)mock服務(wù)州泊。
你可以在這里獲取該項(xiàng)目的服務(wù)端和客戶端源碼(客戶端不是非必須的,但是建議使用)
- github: https://github.com/Silwings-git
- gitee: https://gitee.com/silwings
如有建議或疑問丧蘸,歡迎給我發(fā)送郵件說明,感謝您的意見.
郵箱: silwings@163.com
適用場(chǎng)景
寫這個(gè)服務(wù)主要是為了應(yīng)對(duì)工作中遇到的一些特殊場(chǎng)景遥皂,比如:
- 對(duì)接第三方接口時(shí),對(duì)方提供的接口沒有測(cè)試環(huán)境力喷,或有調(diào)用次數(shù)限制。
- 如果三方接口有調(diào)用次數(shù)限制(如某簽約服務(wù)測(cè)試環(huán)境發(fā)起合同次數(shù)有限制)演训,可以將需要調(diào)用的接口創(chuàng)建為一個(gè)應(yīng)答器弟孟,設(shè)置合理的返回值,就可以先調(diào)試流程代碼样悟,確認(rèn)流程沒問題后切換請(qǐng)求域名披蕉,調(diào)用實(shí)際接口,減少對(duì)三方接口的調(diào)用次數(shù)乌奇。
- 團(tuán)隊(duì)合作時(shí)没讲,所開發(fā)的功能需要依賴同事的接口,但同事還沒完成接口開發(fā)(前端-后端礁苗,后端-后端)爬凑。
- 這種情況下通常是自己mock一些數(shù)據(jù)進(jìn)行調(diào)試,可以將這些mock數(shù)據(jù)創(chuàng)建到應(yīng)答器中试伙,方便重復(fù)利用嘁信,同時(shí)避免mock代碼忘記刪除等意外情況于样。
- 要調(diào)用的接口是發(fā)起一個(gè)操作流程,操作完成后會(huì)對(duì)我方進(jìn)行回調(diào)潘靖。但發(fā)起操作流程后穿剖,該流程難以完成,或耗時(shí)很長(zhǎng)卦溢。
- 通過使用應(yīng)答器來(lái)響應(yīng)發(fā)起操作流程的接口糊余,并主動(dòng)對(duì)預(yù)定接口進(jìn)行回調(diào),進(jìn)而跳過該操作流程单寂,使主流程和次流程拆分贬芥。
*
該服務(wù)不適合數(shù)據(jù)交互需要加解密的場(chǎng)景
使用說明
安裝說明
運(yùn)行該服務(wù)僅需要一個(gè)Mysql服務(wù),要求不低于8.0版本宣决。
- 在數(shù)據(jù)庫(kù)執(zhí)行項(xiàng)目下src\sqls\init.sql文件
- 修改配置文件的數(shù)據(jù)庫(kù)配置
- 運(yùn)行FastResponderApplication
配置示例
{
"name":"Demo config",
"httpMethod":"GET",
"keyUrl":"/demo/url",
"categoryName":"示例配置",
"delayTime":0,
"tasks":[
{
"conditions":[
"1 == 1",
"${age} >= 10",
"name =IsNotBlank="
],
"content":{
"body":{
"timestemp":"-TSNow(ms)-",
"name":"${name}",
"id":"-UUID()-"
},
"headers":{
"authToken":"8888888888"
},
"httpMethod":"POST",
"params":{
"keyA":[
"key_Av1",
"keyA_v2"
],
"keyB":[
"keyB_v1"
]
},
"requestUrl":"http://localhost:8088/hello/word"
},
"delayTime":2000,
"name":"My http task"
}
],
"results":[
{
"body":null,
"conditions":[
"${age} == 18"
],
"headers":{
"authToken":"-TSFNow(yyyy-MM-dd HH:mm:ss)-"
},
"msg":"Hello Word !",
"resultName":"My Result A"
},
{
"body":null,
"conditions":[
"${age} == 15"
],
"headers":{
},
"msg":null,
"resultName":"My Result B"
}
]
}
字段信息
主體 | 類型 | 描述 | 必填 |
---|---|---|---|
name | string | 應(yīng)答器名稱 | true |
httpMethod | string | 應(yīng)答請(qǐng)求方式(大寫) | true |
keyUrl | string | 應(yīng)答地址 | true |
categoryName | string | 應(yīng)答器分類名稱 | false |
delayTime | long | 應(yīng)答器響應(yīng)延遲時(shí)間(ms),默認(rèn)0 | false |
tasks | array | 應(yīng)答器的任務(wù)集 | false |
|--name | string | 任務(wù)名稱 | true |
|--delayTime | long | 延遲時(shí)間(ms),默認(rèn)0 | false |
|--conditions | array | 任務(wù)執(zhí)行條件 | false |
|--content | obj | 任務(wù)內(nèi)容 | true |
|--|--httpMethod | string | 請(qǐng)求方式(大寫) | true |
|--|--requestUrl | string | 請(qǐng)求地址 | true |
|--|--headers | map | 請(qǐng)求頭 | false |
|--|--params | map | 請(qǐng)求參數(shù)(注意value為字符數(shù)組) | false |
|--|--body | obj | 請(qǐng)求體 | false |
results | array | 返回值列表 | false |
|--resultName | string | 返回值名稱 | true |
|--body | obj | 響應(yīng)體 | false |
|--msg | string | 響應(yīng)內(nèi)容(只有body為null才返回msg) | false |
|--conditions | array | 返回執(zhí)行條件 | false |
|--headers | map | 響應(yīng)頭 | false |
字段簡(jiǎn)述
- 應(yīng)答器配置主要由應(yīng)答器名稱蘸劈,應(yīng)答地址,應(yīng)答請(qǐng)求方式尊沸,任務(wù)集威沫,返回值集五個(gè)部分組成。
- 應(yīng)答地址和應(yīng)答請(qǐng)求方式的組合是唯一的洼专。如果出現(xiàn)沖突會(huì)在保存時(shí)提示壹甥。
- 應(yīng)答地址必須以"/"開頭
- 應(yīng)答請(qǐng)求方式的取值范圍: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE(使用客戶端添加應(yīng)答器時(shí)可以不區(qū)分大小寫)。
- 應(yīng)答器響應(yīng)延遲時(shí)間(delayTime)為接收到請(qǐng)求后壶熏,最快應(yīng)該在多少ms外響應(yīng)(注意是外句柠,不是內(nèi))。
- 應(yīng)答器任務(wù)集:可配置http請(qǐng)求任務(wù)棒假,task會(huì)按順序判斷條件溯职,計(jì)算通過后創(chuàng)建task,在指定延遲后發(fā)起http請(qǐng)求帽哑。
- 返回值集: 可配置多個(gè)返回值谜酒,按照順序執(zhí)行,當(dāng)某一個(gè)返回值條件滿足時(shí)立即返回妻枕。
Task說明
- 當(dāng)應(yīng)答器中包含task時(shí)僻族,在應(yīng)答器對(duì)接口進(jìn)行響應(yīng)之前,會(huì)先遍歷task集屡谐,依次判斷執(zhí)行條件(conditions,如果conditions 是empty愕掏,默認(rèn)為true 锨咙。conditions說明見下文)柠偶,如果條件判斷為true情妖,會(huì)創(chuàng)建task任務(wù),等待執(zhí)行诱担。
- 所有task任務(wù)會(huì)被緩存在一個(gè)無(wú)界延遲隊(duì)列(DelayQueue)中毡证,按照delayTime排序。如果配置的延遲時(shí)間相同蔫仙,多個(gè)task可能同時(shí)執(zhí)行(多線程)料睛。
- task任務(wù)目前提供三個(gè)自定義配置
- httptask.scheduler.thread-pool-size:設(shè)置執(zhí)行task任務(wù)的線程池的核心線程數(shù)。默認(rèn)5
- httptask.resttemplate.connect-timeout:請(qǐng)求連接超時(shí)時(shí)間摇邦。默認(rèn)20000(ms)
- httptask.resttemplate.read-timeout:請(qǐng)求讀取時(shí)間恤煞。默認(rèn)20000(ms)
- task任務(wù)中配置的執(zhí)行條件(conditions),請(qǐng)求地址(requestUrl)施籍,請(qǐng)求頭(headers)居扒,參數(shù)(params),請(qǐng)求體(body)均適用
替換操作符
,替換操作符可以對(duì)字符進(jìn)行一些特定處理(見下文)丑慎。
Result說明
- 當(dāng)應(yīng)答器包含result時(shí)喜喂,在請(qǐng)求處理的最后階段,會(huì)按順序遍歷result集竿裂,依次判斷執(zhí)行條件玉吁,如果判斷為true,會(huì)立即將當(dāng)前result作為響應(yīng)進(jìn)行返回腻异。
- 可以配置兩種類型的返回值诈茧。一是返回一個(gè)簡(jiǎn)單的字符串,二是返回一個(gè)對(duì)象捂掰,分別通過msg和body設(shè)置敢会。但如果msg和body同時(shí)存在曾沈,會(huì)優(yōu)先以body返回。例外的是如果運(yùn)算結(jié)果無(wú)法轉(zhuǎn)換為對(duì)象鸥昏,會(huì)用無(wú)法轉(zhuǎn)換的數(shù)據(jù)替換msg中原本的值塞俱。
- result中配置的響應(yīng)條件(conditions),響應(yīng)頭(headers)吏垮,響應(yīng)內(nèi)容(msg障涯,body)均適用
替換操作符
(見下文)。
condition說明
條件(condition)是用來(lái)確定task或result是否執(zhí)行的表達(dá)式(Expression)集膳汪,也就是一個(gè)集合為一個(gè)condition唯蝶。配置格式為在集合中添加條件表達(dá)式。
- 集合中的每一個(gè)元素(表達(dá)式)之間的關(guān)系可以理解為Java中的
&&
遗嗽,當(dāng)前一個(gè)表達(dá)式結(jié)果為false時(shí)粘我,后面的表達(dá)式不計(jì)算,整個(gè)condition直接返回false痹换。 - 如果條件集合為empty征字,該condition返回true。
- 表達(dá)式格式:參數(shù)A+空格+條件符號(hào)+空格+參數(shù)B娇豫。其中參數(shù)A和參數(shù)B為必填匙姜。如果條件符號(hào)只需要左條件(參數(shù)A),參數(shù)B可以不寫冯痢。條件表達(dá)式的三個(gè)元素之間的空格不可省略氮昧。
- 條件符號(hào)
- 等值條件
-
==
- 如果參數(shù)A和參數(shù)B相等返回true。
- 不區(qū)分?jǐn)?shù)據(jù)類型浦楣,均按照字符串equals進(jìn)行比較
- 全條件符號(hào)袖肥,可以是任意數(shù)值或字符
-
!=
- ==的取反
- 全條件符號(hào),可以是任意數(shù)值或字符
-
==
- 數(shù)值條件
- >
- >=
- <
-
<=
- 區(qū)分?jǐn)?shù)據(jù)類型椒振,如果參數(shù)A和參數(shù)B均可以轉(zhuǎn)換為數(shù)值類型昭伸,會(huì)按照比較符號(hào)邏輯進(jìn)行比較,參數(shù)A或參數(shù)B有不能轉(zhuǎn)換為數(shù)值的澎迎,直接返回false
- 全條件符號(hào)
- 空判條件
- =IsNull=
- =IsNotNull=
- =IsBlank=
-
=IsNotBlank=
- 這四種表達(dá)式運(yùn)算邏輯參考o(jì)rg.apache.commons.lang3.StringUtils的對(duì)應(yīng)方法庐杨。
- 左條件符號(hào),只需要參數(shù)A有值即可夹供。
- 等值條件
- 注意事項(xiàng)灵份!
- param參數(shù)比較特殊,因?yàn)槠渲凳且粋€(gè)數(shù)組哮洽,所有在需要對(duì)url參數(shù)進(jìn)行比對(duì)時(shí)填渠,只有當(dāng)param數(shù)組只有一個(gè)值時(shí),才能正常生效。否則需要手動(dòng)配置待比較的值為一個(gè)數(shù)組氛什,并區(qū)分?jǐn)?shù)組中是字符還是數(shù)值莺葫。
ReplaceOperator替換操作符
替換操作符可以對(duì)字符串進(jìn)行特殊處理,如生成數(shù)據(jù)枪眉,引用數(shù)據(jù)捺檬,通過和condition組合可以進(jìn)行動(dòng)態(tài)邏輯判斷。
同一個(gè)字符串中可以添加多個(gè)替換操作符贸铜,但不允許嵌套堡纬。
- 操作符介紹
-
${}
查詢替換符,可以從請(qǐng)求信息參數(shù)(param蒿秦,path param烤镐,body)中獲取指定字段的值來(lái)對(duì)符號(hào)所在位置進(jìn)行替換。通過在{}之間添加文本來(lái)指定字段棍鳖,支持簡(jiǎn)單Json Path語(yǔ)法和標(biāo)準(zhǔn)Json Path語(yǔ)法炮叶,如果對(duì)標(biāo)準(zhǔn)Json Path不熟悉,可以使用簡(jiǎn)單Json Path快速上手鹊杖。
-
簡(jiǎn)單Json Path語(yǔ)法(該語(yǔ)法為我自定義的簡(jiǎn)單語(yǔ)法)
- 查找最外層key:直接填寫字段名
- 查找內(nèi)層key:填寫多個(gè)字段名悴灵,之間使用英文字符 . 分隔
- 查找數(shù)組指定角標(biāo):填寫字段名+[]扛芽,[]內(nèi)填寫有效角標(biāo)值骂蓖。例:studentList[0],意為獲取studentList的0角標(biāo)對(duì)象
- 查找替換示例1:
- 返回值msg:”你好川尖,我叫{student.age}歲“登下。
- 請(qǐng)求應(yīng)答器的請(qǐng)求的請(qǐng)求體:{"code":"200","student":{"name":"小明","age":20}}
- 得到的結(jié)果msg:”你好,我叫小明,今年20歲“
- 示例2:
- 返回值msg:”你好叮喳,我叫{age}歲“被芳。
- 請(qǐng)求應(yīng)答器的請(qǐng)求:http://localhost:8080/getStudent?name=小明&age=20
- 得到的結(jié)果msg:”你好,我叫小明,今年20歲“
- 如果指定的key對(duì)應(yīng)的值是一個(gè)對(duì)象馍悟,將得到一個(gè)對(duì)象或?qū)ο蟮膉son字符串
- 示例3:
- 返回值msg:”你好畔濒,我叫{age}歲“。
- 配置的應(yīng)答地址: http://localhost:8080/getStudent/{name}/{age}
- 請(qǐng)求應(yīng)答器的請(qǐng)求:http://localhost:8080/getStudent/小明/20
- 得到的結(jié)果msg:”你好锣咒,我叫小明,今年20歲“
-
標(biāo)準(zhǔn)Json Path
標(biāo)準(zhǔn)Json Path指由Fast Json提供的Json Path語(yǔ)法規(guī)則侵状,該語(yǔ)法可被JSONPath類解析。語(yǔ)法規(guī)則如下(想要了解更多信息請(qǐng)閱讀fast json相關(guān)文檔):
JSONPATH 描述 $ 根對(duì)象毅整,例如$.name [num] 數(shù)組訪問趣兄,其中num是數(shù)字,可以是負(fù)數(shù)悼嫉。例如$[0].leader.departments[-1].name [num0,num1,num2...] 數(shù)組多個(gè)元素訪問艇潭,其中num是數(shù)字,可以是負(fù)數(shù),返回?cái)?shù)組中的多個(gè)元素蹋凝。例如$[0,3,-2,5] [start:end] 數(shù)組范圍訪問鲁纠,其中start和end是開始小表和結(jié)束下標(biāo),可以是負(fù)數(shù)鳍寂,返回?cái)?shù)組中的多個(gè)元素房交。例如$[0:5] [start:end :step] 數(shù)組范圍訪問,其中start和end是開始小表和結(jié)束下標(biāo)伐割,可以是負(fù)數(shù)候味;step是步長(zhǎng),返回?cái)?shù)組中的多個(gè)元素隔心。例如$[0:5:2] [?(key)] 對(duì)象屬性非空過濾白群,例如$.departs[?(name)] [key > 123] 數(shù)值類型對(duì)象屬性比較過濾,例如$.departs[id >= 123]硬霍,比較操作符支持=,!=,>,>=,<,<= [key = '123'] 字符串類型對(duì)象屬性比較過濾帜慢,例如$.departs[name = '123'],比較操作符支持=,!=,>,>=,<,<= [key like 'aa%'] 字符串類型like過濾唯卖, 例如$.departs[name like 'sz*']粱玲,通配符只支持% 支持not like [key rlike 'regexpr'] 字符串類型正則匹配過濾, 例如departs[name like 'aa(.)*']拜轨, 正則語(yǔ)法為jdk的正則語(yǔ)法抽减,支持not rlike [key in ('v0', 'v1')] IN過濾, 支持字符串和數(shù)值類型 例如: .departs[id not in (101,102)] [key between 234 and 456] BETWEEN過濾, 支持?jǐn)?shù)值類型,支持not between 例如: .departs[id not between 101 and 201] length() 或者 size() 數(shù)組長(zhǎng)度橄碾。例如$.values.size() 支持類型java.util.Map和java.util.Collection和數(shù)組 . 屬性訪問卵沉,例如$.name .. deepScan屬性訪問,例如$..name * 對(duì)象的所有屬性法牲,例如$.leader.* ['key'] 屬性訪問史汗。例如$['name'] ['key0','key1'] 多個(gè)屬性訪問。例如$['id','name'] -
簡(jiǎn)單path和標(biāo)準(zhǔn)path在使用上的區(qū)別:
- 簡(jiǎn)單版除了body拒垃,還支持從param停撞,path param中查找,而標(biāo)準(zhǔn)版僅支持從請(qǐng)求體body中查找悼瓮。
- 簡(jiǎn)單版僅提供簡(jiǎn)單的鍵值查詢戈毒,標(biāo)準(zhǔn)版提供的查詢更加多樣性。
-
簡(jiǎn)單版和標(biāo)準(zhǔn)版共存谤牡,是否會(huì)導(dǎo)致取值錯(cuò)誤副硅?
- 設(shè)計(jì)上,簡(jiǎn)單版和標(biāo)準(zhǔn)版僅有 從集合獲取指定一個(gè)角標(biāo)處的值 的語(yǔ)法相同翅萤,所以也只有這里可能會(huì)發(fā)生簡(jiǎn)單版和標(biāo)準(zhǔn)版沖突的情況恐疲。(這段語(yǔ)法設(shè)計(jì)為相同是為防止對(duì)使用者學(xué)習(xí)標(biāo)準(zhǔn)Json Path造成負(fù)面影響而有意為之)
- 如果簡(jiǎn)單版和標(biāo)準(zhǔn)版均獲取到了值腊满,將優(yōu)先獲取標(biāo)準(zhǔn)版的結(jié)果
-
-
-RDBoolean()-
- 隨機(jī)一個(gè)布爾值替換掉操作符
- 示例:
- 字符串: “這是一個(gè)隨機(jī)布爾值:-RDBoolean()-”
- 結(jié)果: “這是一個(gè)隨機(jī)布爾值:true”
-
-RDInt()-
- 隨機(jī)一個(gè)int數(shù)值替換掉操作符
- 可以在()中傳遞參數(shù)(下列10,-5,20均為示例值,可換其他值)培己。
- -RDInt()-:返回一個(gè)偽隨機(jī)int值碳蛋。
- -RDInt(10)-:返回0(包含)到10(不包含)直接的位隨機(jī)數(shù)int值。
- -RDInt(-5省咨,20)-:返回-5(包括)和20(不包括)之間的偽隨機(jī)int值肃弟。
-
-RDLong()-
- 隨機(jī)一個(gè)long數(shù)值替換掉操作符
- 可以在()中傳遞參數(shù)(下列10,-5,20均為示例值,可換其他值)零蓉。
- -RDLong()-:返回一個(gè)偽隨機(jī)long值笤受。
- -RDLong(10)-:返回0(包括)和10(不包括)之間的偽隨機(jī)long值。
- -RDLong(-5,20)-:返回-5(包括)和20(不包括)之間的偽隨機(jī)long值敌蜂。
-
-RDDouble()-
- 隨機(jī)一個(gè)double數(shù)值替換掉操作符
- 可以在()中傳遞參數(shù)(下列10.0,-5.0,1.0均為示例值箩兽,可換其他值)。
- -RDDouble()-:返回0(包括)和1(不包括)之間的偽隨機(jī)double值章喉。
- -RDDouble(10.0)-:返回介于 0.0(包括)和10.0(不包括)之間的偽隨機(jī)double值汗贫。
- -RDDouble(-5.0,1.0)-:返回-5.0(包括)和1.0(不包括)之間的偽隨機(jī)double值。
-
-UUID()-
- 隨機(jī)一個(gè)uuid替換掉操作符
- 可以在()中傳遞限制長(zhǎng)度(下列16,64均為示例值秸脱,可換其他值)落包。
- -UUID()-:返回一個(gè)uuid字符
- -UUID(16)-:使用substring函數(shù)將uuid裁剪到長(zhǎng)度16
- -UUID(64)-:循環(huán)拼接生成的uuid,知道長(zhǎng)度到達(dá)64
-
-TSNow()-
- 生成當(dāng)前時(shí)間的時(shí)間戳替換掉操作符
- 可以在()中傳遞參數(shù),ms和s為固定值摊唇,只能二選一
- -TSNow()-:時(shí)間戳咐蝇,單位ms
- -TSNow(ms)-:生成毫秒值時(shí)間戳
- -TSNow(s)-:生成秒值時(shí)間戳
-
-TSFNow()-
- 根據(jù)指定格式生成時(shí)間
- 可以在()中傳遞參數(shù)(下列yyyy-MM-dd HH:mm:ss為示例值,可切換其他正確時(shí)間格式)
- -TSFNow()-:同“-TSNow()-”
- -TSFNow(yyyy-MM-dd HH:mm:ss)-:將當(dāng)前時(shí)間轉(zhuǎn)換為“yyyy-MM-dd HH:mm:ss”格式返回
-
客戶端操作與功能演示
強(qiáng)烈推薦使用Web客戶端對(duì)應(yīng)答器進(jìn)行維護(hù)。你可以在我的倉(cāng)庫(kù)中找到它遏片。
使用配置示例中的應(yīng)答器進(jìn)行演示嘹害。
-
創(chuàng)建并啟用應(yīng)答器
- 啟動(dòng)用于回調(diào)的測(cè)試服務(wù),其中包含如下web接口
-
Postman測(cè)試
- 不觸發(fā)任務(wù)和返回值
- 觸發(fā)ResultA
- 觸發(fā)ResultB
- 觸發(fā)Task,ResultB
-
查看日志
實(shí)際使用過程中撮竿,經(jīng)常會(huì)需要確認(rèn)task或項(xiàng)目執(zhí)行情況吮便,如果只能通過控制臺(tái)查看會(huì)比較麻煩,F(xiàn)ast Responder客戶端提供了實(shí)時(shí)日志查看功能幢踏。默認(rèn)日志等級(jí)INFO髓需,可通過配置文件(logback.xml)調(diào)整。日志接口默認(rèn)各接收最多同時(shí)10個(gè)連接房蝉,有新連接進(jìn)入時(shí)僚匆,最早連接的連接將被斷開。
- task日志搭幻,僅打印task執(zhí)行線程的日志
- 項(xiàng)目日志咧擂,打印項(xiàng)目的全部日志
tips:
- 進(jìn)行過編輯后,會(huì)自動(dòng)禁用檀蹋,需要重新啟用松申。
- keyUrl和httpMethod的組合應(yīng)該是唯一的,但數(shù)據(jù)庫(kù)并沒有做限制,所有如果出現(xiàn)重復(fù)并同時(shí)啟用的情況贸桶,將按照數(shù)據(jù)庫(kù)默認(rèn)排序獲取第一個(gè)結(jié)果舅逸。
感謝你的閱讀!