范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

JiraAPI的踩坑记

  我本来是想写篇文章,吐槽一下jira的api的,但是发现最终jira api,很多地方又让我学到了一些新知识。有些方面真的是没见过这么标准使用的。可能是我之前孤陋寡闻啦,所以本文的内容不仅仅是讲jira的坑, 还有一些是jira本身优良的品性,不仅让我学到了一些知识,也让我对规范有了新的理解。 本文的内容算是对我最近这段时间以来对接jira API的经验总结,希望能对各位有所帮助。  没有中文
  这个是对我来说最大的困难,本身我的英文水平不好之前,阅读文档或者说是一些文章都是直接一键翻译,但是碰到jira的API文档就有点蒙逼了。 本来我以为在国内有很多公司都在用jira, 这里面少不了的API接口进行功能性的封装,肯定会有中文的文档结果经过几次尝试搜索之后,我终于确认jira API是没有中文文档的。
  我使用的一键翻译软件是浏览器自带的尝试过一些,他们总是会把接口请求路径中的英文单词也翻译成汉字,这简直就是不能看。 虽然如此,我还是需要中文翻译和英文原文对照着看,因为有些地方翻译成中文之后语序不是那么通顺。总体来说,没有中文文档对App的接入还是有挺大影响的,因为需要不断地去对照着英文原文和理解翻译之后的结果。
  在我搜索中文文档的过程中,我看到网上有很多人对API的实现进行了分享,对我来说还是有点大帮助的。 但内容比较少,仅限于两三个特别常用的API。 没有人完整的翻译过jira API的文档,然后我发现了一个巨坑的事情: jira App文档分嗯多个版本,基本上每一个版本的基拉就对应一个版本的API文档,我没有仔细去看这里面的区别,但是我觉得一个版本一个文档,着实有点坑了。 大家如果有机会对接jira API文档,到时候一定要首先确认jira的版本。  HTTPcode
  在jira API文档中,http协议响应状态码有很多使用。在我之前的工作经历中,很少注意到http响应状态码这个数据。 因为大多数情况都是成功的话,返回200,不成功的话也是返回200(通过业务状态码来区分不同原因), 只有在接口请求失败,或者说服务器故障的时候会处理一下400和500系列的响应状态码。 在对接Jira API文档的过程中,我遇到了很多种之前没有接触过的200系列的http协议响应状态码。Jira API 是通过http,响应状态码来表示业务处理状态,他并没有使用业务状态码。 所以,在对接的过程中,需要单独处理每个接口的http响应状态码。
  在POST和PUT全球方法的接口, 很少能看到200的状态响应码。 下面分享一下,我常见到的201和204状态响应码的标准规范。  201 Created
  请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 "202 Accepted"。  204 No Content
  服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。响应可能通过实体头部的形式,返回新的或更新后的元信息。如果存在这些头部信息,则应当与所请求的变量相呼应。如果客户端是浏览器的话,那么用户浏览器应保留发送了该请求的页面,而不产生任何文档视图上的变化,即使按照规范新的或更新后的元信息应当被应用到用户浏览器活动视图中的文档。由于204响应被禁止包含任何消息体,因此它始终以消息头后的第一个空行结尾。  响应不统一
  在之前文章一起吐槽接口文档中, 我吐槽了一下,接口文档最坑的就是响应不统一,没想到在对接Jira文档的时候就出现了特别多这样的实践机会。我曾经一度怀疑Jira文档是不是故意这么做的,因为各个接口的响应结果。均为json形式,但是最外层的json响应结构。有点1000个接口有1000个响应的即视感。
  我之前写项目测试框架的时候,都会对响应结果进行统一的json格式处理,但是对于Jira的api就没有办法使用统一的格式处理,每一个接口都需要进行单独的处理。这无疑也增加了工作量。下面分享我遇到的几种响应结构。  {     "issues": [         {             "id": "10000",             "key": "TST-24",             "self": "http://www.example.com/jira/rest/api/2/issue/10000"         },         {             "id": "10001",             "key": "TST-25",             "self": "http://www.example.com/jira/rest/api/2/issue/10001"         }     ],     "errors": [] } {     "id": "10000",     "key": "TST-24",     "self": "http://www.example.com/jira/rest/api/2/issue/10000" }
  下面这种就属于比较霸王级别的难看。一个响应结构体去。表示编辑之后的issues的状态。结果没想到在JSON对象中包了这么多层。为了让文章能缩短一下,我把里数组重复的内容给删除了,但是还是有这么复杂的响应结构体,简直就是丧心病狂!  {     "id": "https://docs.atlassian.com/jira/REST/schema/issue-update#",     "title": "Issue Update",     "type": "object",     "properties": {         "transition": {             "title": "Transition",             "type": "object",             "properties": {                 "id": {                     "type": "string"                 },                 "name": {                     "type": "string"                 },                 "to": {                     "title": "Status",                     "type": "object",                     "properties": {                         "statusColor": {                             "type": "string"                         },                         "description": {                             "type": "string"                         },                         "iconUrl": {                             "type": "string"                         },                         "name": {                             "type": "string"                         },                         "id": {                             "type": "string"                         },                         "statusCategory": {                             "title": "Status Category",                             "type": "object",                             "properties": {                                 "id": {                                     "type": "integer"                                 },                                 "key": {                                     "type": "string"                                 },                                 "colorName": {                                     "type": "string"                                 },                                 "name": {                                     "type": "string"                                 }                             },                             "additionalProperties": false                         }                     },                     "additionalProperties": false                 },                 "fields": {                     "type": "object",                     "patternProperties": {                         ".+": {                             "title": "Field Meta",                             "type": "object",                             "properties": {                                 "required": {                                     "type": "boolean"                                 },                                 "schema": {                                     "title": "Json Type",                                     "type": "object",                                     "properties": {                                         "type": {                                             "type": "string"                                         },                                         "items": {                                             "type": "string"                                         },                                         "system": {                                             "type": "string"                                         },                                         "custom": {                                             "type": "string"                                         },                                         "customId": {                                             "type": "integer"                                         }                                     },                                     "additionalProperties": false                                 },                                 "name": {                                     "type": "string"                                 },                                 "autoCompleteUrl": {                                     "type": "string"                                 },                                 "hasDefaultValue": {                                     "type": "boolean"                                 },                                 "operations": {                                     "type": "array",                                     "items": {                                         "type": "string"                                     }                                 },                                 "allowedValues": {                                     "type": "array",                                     "items": {}                                 }                             },                             "additionalProperties": false,                             "required": [                                 "required"                             ]                         }                     },                     "additionalProperties": false                 }             },             "additionalProperties": false         },         "fields": {             "type": "object",             "patternProperties": {                 ".+": {}             },             "additionalProperties": false         },         "update": {             "type": "object",             "patternProperties": {                 ".+": {                     "type": "array",                     "items": {                         "title": "Field Operation",                         "type": "object"                     }                 }             },             "additionalProperties": false         },         "historyMetadata": {             "title": "History Metadata",             "type": "object",             "properties": {                 "type": {                     "type": "string"                 },                 "description": {                     "type": "string"                 },                 "descriptionKey": {                     "type": "string"                 },                 "activityDescription": {                     "type": "string"                 },                 "activityDescriptionKey": {                     "type": "string"                 },                 "emailDescription": {                     "type": "string"                 },                 "emailDescriptionKey": {                     "type": "string"                 },                 "actor": {                     "$ref": "#/definitions/history-metadata-participant"                 },                 "generator": {                     "$ref": "#/definitions/history-metadata-participant"                 },                 "cause": {                     "$ref": "#/definitions/history-metadata-participant"                 },                 "extraData": {                     "type": "object",                     "patternProperties": {                         ".+": {                             "type": "string"                         }                     },                     "additionalProperties": false                 }             },             "additionalProperties": false         },         "properties": {             "type": "array",             "items": {                 "title": "Entity Property",                 "type": "object",                 "properties": {                     "key": {                         "type": "string"                     },                     "value": {}                 },                 "additionalProperties": false             }         }     },     "definitions": {         "history-metadata-participant": {             "title": "History Metadata Participant",             "type": "object",             "properties": {                 "id": {                     "type": "string"                 },                 "displayName": {                     "type": "string"                 },                 "displayNameKey": {                     "type": "string"                 },                 "type": {                     "type": "string"                 },                 "avatarUrl": {                     "type": "string"                 },                 "url": {                     "type": "string"                 }             },             "additionalProperties": false         }     },     "additionalProperties": false } 包装过度
  在通常所用到的接口文档中的接口参数,一般都是通过key value形式去传参。比较复杂的,可能会用到数组。但是在对接Jira文档的时候,我发现完全不能以之前的思维惯性去理解Jira API文档中的接口参数传递方式。如果说通常接口参数通过JSON包装一层的话,那么Jira文档的接口参数就是里三层外三层。下面我通过几个实例给大家真实的再现一下鸡爪文档中接口参数的复杂性。  {     "update": {         "worklog": [             {                 "add": {                     "timeSpent": "60m",                     "started": "2011-07-05T11:05:00.000+0000"                 }             }         ]     },     "fields": {         "project": {             "id": "10000"         },         "summary": "something"s wrong",         "issuetype": {             "id": "10000"         },         "assignee": {             "name": "homer"         },         "reporter": {             "name": "smithers"         },         "priority": {             "id": "20000"         },         "labels": [             "bugfix",             "blitz_test"         ],         "timetracking": {             "originalEstimate": "10",             "remainingEstimate": "5"         },         "security": {             "id": "10000"         },         "versions": [             {                 "id": "10000"             }         ],         "environment": "environment",         "description": "description",         "duedate": "2011-03-11",         "fixVersions": [             {                 "id": "10001"             }         ],         "components": [             {                 "id": "10000"             }         ],         "customfield_30000": [             "10000",             "10002"         ],         "customfield_80000": {             "value": "red"         },         "customfield_20000": "06/Jul/11 3:25 PM",         "customfield_40000": "this is a text field",         "customfield_70000": [             "jira-administrators",             "jira-software-users"         ],         "customfield_60000": "jira-software-users",         "customfield_50000": "this is a text area. big text.",         "customfield_10000": "09/Jun/81"     } } {     "startAt": 0,     "maxResults": 1,     "total": 1,     "comments": [         {             "self": "http://www.example.com/jira/rest/api/2/issue/10010/comment/10000",             "id": "10000",             "author": {                 "self": "http://www.example.com/jira/rest/api/2/user?username=fred",                 "name": "fred",                 "displayName": "Fred F. User",                 "active": false             },             "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eget venenatis elit. Duis eu justo eget augue iaculis fermentum. Sed semper quam laoreet nisi egestas at posuere augue semper.",             "updateAuthor": {                 "self": "http://www.example.com/jira/rest/api/2/user?username=fred",                 "name": "fred",                 "displayName": "Fred F. User",                 "active": false             },             "created": "2016-09-27T09:43:02.795+0000",             "updated": "2016-09-27T09:43:02.795+0000",             "visibility": {                 "type": "role",                 "value": "Administrators"             }         }     ] }
  以上两个是我用遇到的比较麻烦的两个接口的传参方式,大家看起来可能会比较复杂。也有点儿迷惑,但其实这两个接口都不算。最复杂的,因为他案例中这些参数的值大部分是可以不传的。Jira API文档中 最让我感觉到不爽的,还不是这种里山城外三成的包装方式, 而是同一个参数,可能会出现在多个包装结构中。 而且这些包装结构的作用范围并没有在文档中标识出来,导致我想去查一个参数,并不知道两个地方现在多个地方到底哪个地方有用只能去一各一各的尝试,虽然对接文档的工作已经完成了,但是对于文档中所标记的参数以及传参格式部分字段依然稀里糊涂。反正功能已经实现啦,就先不去管它啦。  Demo错误
  接口文档中最难以让人忍受的就是接口文档中存在着硬性错误。本来对接接口文档已经是一个比较麻烦的事情了。如果文档中出现一些硬性的错误。会让我付出更多的时间和精力去纠正这些错误,如果再碰到非常复杂的包装格式,就更让人恼火了。回到刚才提到过的Jira api文档,有非常多个版本,如果文档出现错误,修复起来肯定也是比较多的。我一度认为他这个文档就是通过工具直接生成的。跟源码中的文档标记很相似。
  下面分享一条文档中的错误,这是一个接口传参格式的Demo。乍一看其实没什么问题,但是这其实并不是JSON的标准格式。在我们阅读文档的时候首先就,首先就是要解析出这个中接口传参格式的JSON展示,我们才能知道具体在JSON好在传参的时候,在哪一层去传什么样的参数。  {"update":{"summary":[{"set":"Bug in business logic"}],"components":[{"set":""}],"timetracking":[{"edit":{"originalEstimate":"1w 1d","remainingEstimate":"4d"}}],"labels":[{"add":"triaged"},{"remove":"blocker"}]},"fields":{"summary":"This is a shorthand for a set operation on the summary field","customfield_10010":1,"customfield_10000":"This is a shorthand for a set operation on a text custom field"},"historyMetadata":{"type":"myplugin:type","description":"text description","descriptionKey":"plugin.changereason.i18.key","activityDescription":"text description","activityDescriptionKey":"plugin.activity.i18.key","actor":{"id":"tony","displayName":"Tony","type":"mysystem-user","avatarUrl":"http://mysystem/avatar/tony.jpg","url":"http://mysystem/users/tony"},"generator":{"id":"mysystem-1","type":"mysystem-application"},"cause":{"id":"myevent","type":"mysystem-event"},"extraData":{"keyvalue":"extra data","goes":"here"}},"properties":[{"key":"key1","value":"properties" : "can be set at issue create or update time"},{"key":"key2","value":"and" : "there can be multiple properties"}]}
  其实问题出现在最后一个 "properties":[{"key":"key1","value":"properties" : "can be set at issue create or update time"},{"key":"key2","value":"and" : "there can be multiple properties"}]  ,后面的can be  其实是对这个参数的描述,不知道怎么到了接口的传参Demo里面了。着实让人头大。 中英混排
  Jira的api文档都是英文版的,我一度怀疑他并不重视中国区用户,但是当我看到某些接口的字段值的时候,我一下子震惊了,原来他的字段值还是中英混排的。一下子有点儿不知所措。如图所示:
  jira上issue状态
  issue状态中居然有中文。真是让我感动的痛哭涕零,这都什么玩意儿。  POST PUT
  在我之前的工作当中,主要接触的还是get和post接口。对于其他HTTP请求方式并不十分了解,也不太清楚这其中的规范。一直以来的概念就是获取数据用get,修改数据用post。但是在接触Jira API文档的过程中,我仔细地看了看post和PUT的区别。总结如下:  创建用POST,修改PUT  POST非幂等,PUT幂等
  在传参格式上,post和put都一样。设置请求entity的方式也是一样的,在Java代码中是通用的,原因在于 org.apache.http.client.methods.HttpPut  和org.apache.http.client.methods.HttpPost  都继承于抽象类org.apache.http.client.methods.HttpEntityEnclosingRequestBase  。这个小知识点我又重新学习了一遍。
  Have Fun ~ Tester !

2022年五一小长假去哪里,还能远行出游吗?五一小长假即将来临,内心是不是很澎湃,无法平复,身体充满了用不完的力气,我要出去玩,我要看一下,伟大祖国的大好河山!平时我的眼界太狭小了,我要体验一下会当凌绝顶,一览众山小的壮举,提醒有了甲状腺结节,最好别碰3绿,做到3戒,或可消散结节你每年做体检了吗?现在越来越多的人重视身体健康了因为现在生活条件好了谁不想多活几年了,你说是吧?如果有一点小病小痛,能及时发现,早点治疗,让身体保持一个健康的状态,这样就能提高生活建议中老年人春夏交替湿气重!多吃5种祛湿菜,早吃早受益建议中老年人春夏交替湿气重!多吃5种祛湿菜,早吃早受益每年一到春夏交替的时节,雨水就增多了,时不时就会下场雨,导致湿气比较重,所以上了年纪的朋友要多注意,除了要多运动之外,还要在饮回南天湿气重,煲靓汤好祛湿根据最新天气预报,接下来的几天,雨将与你天天见。这样的阴雨天,不少老广都喜欢煲些祛湿汤或祛湿茶给家人喝。但要注意的是,湿有内外之别,还有寒热之分。想喝汤水祛湿,要先学会辨病因分证型做好这5项健康一整年春分之后要养生。春分,其实有两层意思一是,这一天阳光几乎直射赤道,南北半球昼夜平分,各为12小时,此后阳光直射位置逐渐北移,北半球开始昼长夜短。二是,古时以立春至立夏为春季,春分正小米粥不能当早餐?医生不只小米粥,这5早餐也尽量住口爱乐养生指南早餐是一天中最重要的一餐,只有早餐摄入足够的能量和营养物质,才能让一整天保持良好状态。经过有关专家分析认为,人体所需要的能量主要来源于糖分,其次是依靠脂肪分解氧化,由于男性注意脑梗发生,或与这几个习惯有关,如果你也有,尽早戒掉脑梗是由于脑部供血障碍缺血缺氧引起的局部脑组织缺血性疾病。临床资料显示,男性脑梗死患者的比例远高于女性患者。这与中国男性的生活习惯密切相关。以下四个习惯如果你也有,趁早改掉吧!一长这个五一我不去玉渊潭了玉渊潭因水得名,辽金时称钓鱼台,元朝又名玉渊潭,清乾隆皇帝在此修建行宫。800多年来一直是北京著名的旅游胜地。1960年北京市政府定为玉渊潭公园,称为市民休闲娱乐场所。玉渊潭公园最建议家长,春天多给孩子做4道营养菜,促进钙吸收,吃得好长高个导语建议家长,春天多给孩子做4道营养菜,促进钙吸收,吃得好长高个家里有孩子,每天都需要认真做菜,不能马虎对待,建议家长,春天多给孩子做4道营养菜,促进钙吸收,吃得好长高个!这几道菜你认为老一辈最糟糕的育儿建议是什么?说到老一辈的育儿建议,估计有很多宝妈会抱怨。但是老一辈的育儿经验也不能说都不正确,毕竟他们也有总结出对的经验。不过有些经验也确实是有问题的。现在随着科学育儿观念的深入,跟老一辈的一阿联周鹏做错什么?全网建议两人退役别祸害球队,广东队该重建吗广东队4年来首次无缘总决赛,半决赛广东队03输给辽宁队后,网上就出现广东队应该重建,广东队应该让周鹏易建联退役,两人的低迷表现才是广东队输球的最大原因,两人真的是广东队输球的罪臣吗
2023,你最想去新的一年,你最想去的地方是哪里?无论是塞北还是江南,高原还是平原,那个被我们埋藏在心底整整三年的远方,终于有机会抵达。深圳变得很空,曾在这里忙忙碌碌的人们,或是奔赴家乡,或是飞向远跨域延伸,链式推进成渝绵眉新型显示产业竞合之路链群化是电子信息产业发展的特色之一,集群成势链式推进对于新型显示产业而言具有倍增效应。成都重庆绵阳眉山四地均在新型显示领域拓底蕴优布局重特色,如若协力聚焦新型显示领域打造现代产业集男过四十,4个特征表明你已经提前衰老,该如何预防呢?老张今年46岁,原本大门不出二门不迈的他,最近突然开始锻炼身体,还尤其注重饮食。不过最让人费解的,是老张最近竟然异常看重自己的脸。老伴看着镜子面前照来照去的老张,当真是感到极其别扭太抢手!大二男生回村后被疯狂预约,全凭这门手艺!大学生们都已经在过寒假了吧回村后的大学生们都在干什么?扬州大学旅游烹饪学院烹饪与营养教育专业大二学生潘澄寒假回盐城老家后奔走各家为村民们忙年菜包包子炸肉圆凭实力成为村里超抢手的人当霸王别姬龙凤斗双椒茄子霸王别姬食材配料甲鱼母鸡冬笋葱花生姜大蒜青椒白芝麻老抽冰糖腐乳黄豆酱蚝油生抽白糖白胡椒粉红油制作步骤甲鱼宰杀后放入开水中浸泡30秒,撕掉腹部和四肢壳上的膜以及内里的黄油,剁成块,放以大家都爱汾酒为引,汾酒与消费者共享同一份热爱从古至今,酒都是中国人节礼之时不可或缺的重要一份子。无酒不成席无酒不成礼,酒几乎见证了中国人一生中所有重要时刻。作为中国酒魂,汾酒始终是中国酒文化的见证者,一脉清香承载了历久弥香的被低估的灯芯绒套装,今冬上分了!越来越多的灯芯绒单品以套装形式出现,一整套穿下来时髦得让人挪不开眼!图片来源微博驼色灯芯绒套装灯芯绒套装比较拉风,但意外很上镜。一般咖啡色灯芯绒年代感重一些,这时搭配的配饰就需要稍甲油胶出口知多少来源12360服务订阅号甲油胶又名美甲胶,是光疗美甲不可或缺的基础原料,用于改变天然指甲的外观和颜色,在美甲行业应用比较广泛。近年来,随着国际市场对美甲产品的需求强劲,催生了国内甲散文贾平凹美食家美食家文贾平凹同事者见了我,总是劝我吃好,而且说,你又不是吃不起!这么一说,我倒像是个守财奴,吝啬鬼,或者偏要做个苦行僧似的,刻意儿吃坏食物。其实我也知道吃是人最重要的工作,鸟为食向太同框何超琼输太惨!一个碎花裙扮嫩却显老,一个黑裙优雅大气女性年轻的时候就算长的再惊艳动人,到老了之后也一定要优雅老去,坦然的面对年龄的增长,以及外在的变化,才能够真正的忽略掉自己的年纪,活的更加潇洒自然。上了年纪之后,穿衣打扮也要改变一把财产全交给妻子的5位男星,个个身家过亿,妻子都不简单都说娱乐圈里的感情真真假假,来得快也去得快,但是也有不少明星,和另外一半的感情是在相处的过程中越来越好的。小8盘点的5位男星,他们日常十分宠爱妻子,连财政大权都交出去了,结婚几十年