1。スワッガーの紹介
前の記事では、RestfulのSpring Bootのサポートを紹介しました。この記事では、このトピックについて説明し続けています。ただし、Restful APIがどのように実装されているかについては、Restful APIドキュメントのメンテナンスについて説明します。
毎日の仕事では、フロントエンド(Web End、iOS、Android)またはサードパーティにインターフェイスを提供する必要があることがよくあります。現時点では、詳細なAPIドキュメントを提供する必要があります。しかし、詳細なドキュメントを維持することは簡単な作業ではありません。まず第一に、詳細なドキュメントを書くことは、時間がかかり、面倒な作業です。一方、コードとドキュメントは分離されているため、ドキュメントとコードの間で矛盾を引き起こすのは簡単です。この記事では、APIドキュメントを維持する方法、つまりSwaggerを通じてRestuful APIドキュメントを自動的に生成する方法を共有します。
では、スワッガーとは何ですか?公式の説明を直接読むことができます。
世界で最も人気のあるAPI Toolingswaggerは、Openapi仕様(OAS)のAPI開発者ツールの世界最大のフレームワークであり、設計やドキュメンテーションからテストと展開まで、APIライフサイクル全体の開発を可能にします。
このパッセージは、Swaggerが世界で最も人気のあるAPIツールであり、Swaggerの目的は、設計、ドキュメント、テスト、展開など、APIライフサイクル全体の開発をサポートすることであることを示しています。この記事では、Swaggerのドキュメント管理とテスト機能を使用します。
Swaggerの役割を基本的に理解した後、それをどのように使用するかを見てみましょう。
2。SwaggerおよびSpring Boot Integration
ステップ1:対応するJARパッケージを紹介します。
<依存関係> groupId> io.springfox </groupid> <artifactid> springfox-swagger2 </artifactid> <version> 2.6.0 </version> </dependency> <dependency> <groupid> io.springfox </groupid> <artifactid> springfox-swox-verion </artificid> </</</</</</</<
ステップ2:基本情報構成:
@configuration @enableSwagger2public class swagger2config {@bean public docket createrestapi(){return new docket(documentationType.swagger_2).apiinfo().select().apis(requesthandlerselectors.basepackage( "com.pandy.blog.rest") .paths(pathselectors.regex( "/rest/.*")).build(); } private apiinfo apiinfo(){return new Apiinfobuilder().title( "Blog System Restful API").Description( "Blog System Restful API")。 。建てる(); }}基本的な構成は、APIドキュメント全体といくつかのグローバル構成の説明であり、すべてのインターフェイスで機能します。ここには2つの注釈が関係しています。
@Configurationは、これがJDKによって提供された構成クラス、注釈であり、前の記事で説明されていることを意味します。
@enableSwagger2の関数は、swagger2関連の関数を有効にすることです。
この構成クラスでは、主に情報の3つの側面を含むドケットオブジェクトをインスタンス化しました。
(1)API全体の説明情報、つまりAPIINFOオブジェクトに含まれる情報、情報のこの部分がページに表示されます。
(2)APIドキュメントを生成するパッケージ名を指定します。
(3)APIを生成するパスを指定します。パスベースのAPIは4つのモードをサポートできます。これは、ソースコードを参照するために使用できます。
public class pathselectors {private pathselectors(){supportedoperationexception(); } public static Predicate <String> any(){return Predicates.alwayStrue(); } public static predicate <string> none(){return predicates.alwaysfalse(); } public static predicate <string> regex(final string pathregex){return new Predicate <String>(){public boolean apply(string input){return input.matches(pathregex); }}; } public static predicate <string> ant(final string antpattern){return new Predicate <string>(){public boolean apply(string input){antpathmatcher matcher = new antpathmatcher(); return matcher.match(antpattern、input); }}; }}ソースコードからわかるように、Swaggerは4つの方法をサポートしています:あらゆるパスの生成、あらゆるパスの非生成、および通常のマッチングとAntパターンのマッチング。最初の3つのタイプ、アリのマッチングの最後のタイプに精通しているかもしれません。アリに慣れていない場合は、それを無視してください。最初の3つのタイプは、誰もが毎日の仕事で使用するのに十分なはずです。
上記の構成を使用すると、効果がわかります。 com.pandy.blog.restパッケージの下にArticlerestControllerクラスがあります。ソースコードは次のとおりです。
スプリングブーツを起動してから、http://127.0.0.1:8080/swagger-ui.htmlにアクセスして、次の結果を確認してください。
このページでは、最後のインターフェイス /test /{id}を除いて、他のインターフェイスが対応するドキュメントを生成することを確認できます。最後のインターフェイスは、構成したパス「/rest/.*」を満たしていないため、ドキュメントは生成されません。
また、クリックして各特定のインターフェイスを表示することもできます。例として「投稿 /休憩 /記事」インターフェイスを取り上げましょう。
ご覧のとおり、Swaggerは各インターフェイスの返品結果の例と要求パラメーターを生成し、以下の「試してみてください」を介してインターフェイスに直接アクセスできます。インターフェイスに関しては、誰もがインターフェイスをテストします。全体として、Swaggerは依然として非常に強力であり、構成は比較的単純です。
@RestControllerPublic Class ArticlerestController {@autowired private reciptivice arvice artictervice; @RequestMapping(value = "/rest/article"、method = post、produces = "application/json")public webresponse <map <string、object >> savearticle(@requestbody article){article.setuserid(1L); recutionervice.savearticle(記事); map <string、object> ret = new Hashmap <>(); Ret.put( "id"、article.getId()); webresponse <map <string、object >> response = webresponse.getsuccessResponse(ret);返信応答。 } @RequestMapping(value = "/rest/article/{id}"、method = delete、produces = "application/json")public webresponse <?> deletearticle( @pathvariable long id){article article = articurservice.getbyid(id); article.setstatus(-1); articleService.updateArticle(記事); webresponse <Object> response = webresponse.getSuccessResponse(null);返信応答。 } @RequestMapping(value = "/rest/article/{id}"、method = put = pudes = "application/json")public webresponse <object> updatearticle( @pathvariable long id、 @requestbody article){article.setid(id); articleService.updateArticle(記事); webresponse <Object> response = webresponse.getSuccessResponse(null);返信応答。 } @RequestMapping(value = "/rest/article/{id}"、method = get、produces = "application/json")public webresponse <article> getArticle( @pathvariable long id){article article = articurservice.getbyid(id); webresponse <ports> response = webresponse.getsuccessResponse(article);返信応答。 } @RequestMapping(value = "/test/{id}"、method = get、produces = "application/json")public webresponse <?> getnoapi(){webresponse <?返信応答。 }}3。Swagger APIの詳細な構成
しかし、これを見ると、間違いなくいくつかの質問があります:
最初の質問:リターン結果とリクエストパラメーターの文字通りの説明はありません。これを構成できますか?
2番目の質問:この要求パラメーターはオブジェクトに基づいて直接反映する必要がありますが、オブジェクトのすべてのプロパティが必要ではなく、パラメーターの値が私たちのニーズを満たしていない場合があります。これを構成できますか?
答えは確かに大丈夫です。次に、これら2つの問題を解決し、構成コードを直接調べましょう。
パッケージcom.pandy.blog.rest; Import com.pandy.blog.dto.webreaponse; Import com.pandy.blog.po.article; Import com.pandy.blog.service.articleservice; Import io.swaghe.annotations.apiimplictparam; Import io.annotation.apimplicitparams; io.swagger.annotations.apioperation; Import io.swagger.annotations.apiresponse; Import io.swagger.annotations.apireSponse; Import io.swagger.annotations.apiresponse; Import io.swagger.annotations.apiresponse; Import org.springframework.beans.beans.beans.factory.Annotation.Annotation. org.springframework.context.annotation.profile; Import org.springframework.web.bind.annotation.pathvariable; Import org.springframework.web.bind.annotation.Requestbody; Import org.springframework.web.web.bind.notation.Requestmapping; org.springframework.web.bind.annotation.restcontroller; Import java.util.hashmap; Import java.util.list; Import java.util.map; import static org.springframework.web.bind.annotation.requestmethation.delete; Import static; org.springframework.web.bind.annotation.requestmethod.get; Import static org.springframework.web.bind.annotation.requestmethod.post; Import static org.springframework.web.bind.annotation.requestmethation.retcontroller@requestroller@requestroller articlerestcontroller {@autowired private reciptionservice artictervice; @RequestMapping(value = "/article"、method = post、produces = "application/json")@apioperation(value = "add article"、notes = "add new article"、tags = "article"、httpmethod = "post")@apiimplicitparams( @apiimplicitparam(name = "summary"、value = "article summary"、required = true、datatype = "string")、@apiimplicitparam(name = "status"、value = "publish status"、evenive = "dateType =" integer ")})@apiresponses({@apiresponse =" cude = "custs =" cusces = "cusces =" publasponses " webresponse <map <string、object >> savearticle(@requestbody article article){reciontervice.savearticle(記事); map <string、object> ret = new Hashmap <>(); Ret.put( "id"、article.getId()); webresponse <map <string、object >> response = webresponse.getsuccessResponse(ret);返信応答。 } @apioperation(value = "delete article"、notes = "delete article by id"、tags = "article"、httpmethod = "delete")@apiimplicitparams({@apiimplicitparams(name = "id"、value = "article id"、rebys = true、long " delete、produces = "application/json")public webresponse <?> deletearticle(@pathvariable long id){article article = articureservice.getByid(id); article.setstatus(-1); recutionervice.savearticle(記事); webresponse.getsuccessResponse(new hashmap <>()); } @apioperation(value = "get the article list"、notes = "タイトルによる完全クエリ"、tags = "article"、httpmethod = "get")@apiimplicitparams({@apiimplicitparams(name = "title"、value = "article title"、reby = fals = "string")ページごとに "、必須= false、dataType =" integer ")、@apiimplictparam(name =" pagenum "、value =" pagepage番号 "、必須= false、dataType =" integer ")})@RequestMapping(value ="/article/list "、method = get、inteps" integer pagenum){if(pagesize == null){pagesize = 10; } if(pagenum == null){pagenum = 1; } int offset =(pagenum -1) * pagesize; list <portion> article = articlesvice.getarticles(title、1l、offset、pagesize); webresponse.getsuccessResponse(記事)を返します。 } @apioperation(value = "update article"、notes = "update content"、tags = "article"、httpmethod = "put")@apiimplicitparams({@apiimplicitparams(name = "id"、value = "article id"、required = true、datape = " dataType = "string")、@apiimplicitparam(name = "summary"、value = "article summary"、required = false、dataType = "string")、@apiimplicitparam(name = "status"、value = "publish status"、必須= false、dataType = "integer")}) "Application/json")public Webresponse <? articleService.updateArticle(記事); webresponse.getsuccessResponse(new hashmap <>()); }}コード内のいくつかの注釈と関連属性の特定の機能を説明しましょう。
@Apioperation、インターフェイス属性構成全体:
値:インターフェイスの説明、インターフェイスリストに表示されます。
注:インターフェイスの詳細ページに表示されるインターフェイスの詳細な説明。
タグ:インターフェイスのタグ。同じタグを持つインターフェイスは、タブページの下に表示されます。
HTTPMethod:サポートされているHTTPメソッド。
@APIIMPLICTPARAMのコンテナである@APIIMPLICTPARAMSには、複数の@APIIMPLICTPARAMアノテーションを含めることができます
@apiimplicitparam、リクエストパラメーター属性構成:
名前:パラメーター名
値:パラメーターの説明
必須:必要ですか
データタイプ:データ型
@Apiresponses、@ApireSponseコンテナには、複数の@ApireSponseアノテーションを含めることができます
@Apiresponse、結果属性の構成を返します:
コード:結果のエンコードを返します。
メッセージ:結果の説明を返します。
応答:結果の対応するクラスを返します。
上記の構成を完了したら、ページ効果を見てみましょう。
リストページ:
ご覧のとおり、インターフェイスは記事タグの下に配置され、インターフェイスの背後にある構成の指示もあります。 「投稿 /休憩 /記事」インターフェイスの詳細ページを見てみましょう。
画像が大きすぎて、タイトル属性の表示のみが傍受され、他のパラメーターは似ています。ページから、リクエストパラメーターの指示があることを見ることができますが、これは予想される効果ではありません。パラメーターが単純なタイプである場合、この方法は問題ありませんが、問題はリクエストパラメーターがオブジェクトであることです。これには、@Apimodelと@ApimodelPropertyの2つの他の注釈が含まれます。最初にコードを見てから説明しましょう。理解しやすいです。
@apimodel(value = "article object"、description = "add&update article object object description")public class article {@id @generatedvalue @apimodelproperty(name = "id"、value = "article id"、必須= false、example = "1")private long id; @apimodelproperty(name = "title"、value = "article title"、required = true、example = "test article title")private string title; @ApimodelProperty(name = "summary"、value = "article summary"、required = true、example = "test article summary")private string summary; @apimodelproperty(hidden = true)private date createTime; @apimodelproperty(hidden = true)private date publictime; @apimodelproperty(hidden = true)private date updateTime; @apimodelproperty(hidden = true)private long userid; @apimodelproperty(name = "status"、value = "記事リリースステータス"、必須= true、example = "1")private integer status; @apimodelproperty(name = "type"、value = "article category"、required = true、example = "1")private integerタイプ;}@Apimodelは、クラス全体のプロパティの構成です。
値:クラスの説明
説明:詳細な説明
@ApimodelPropertyは、各フィールドのプロパティの詳細な構成です。
名前:フィールド名
値:フィールドの説明
必須:必要ですか
例:例の例
非表示:表示するかどうか
上記の構成を完了したら、効果を見てみましょう。
これで、フィールドの説明が表示されていることがわかり、この例のフィールドの値は、構成した例のプロパティの対応する値にもなりました。このようにして、完全なAPIドキュメントが生成され、ドキュメントは2つの分離された部分ではなく、コードに密接にリンクされています。さらに、このドキュメントを使用して簡単にテストすることもできます。値の下のイエローボックスをクリックするだけで、内部の内容が記事の対応する値ボックスに自動的にコピーされ、[試してみる]をクリックしてHTTPリクエストを開始します。
[それを試してみてください]をクリックした後、返された結果が表示されます。
操作はまだ非常に便利です。 JunitおよびPostmanと比較して、Swaggerを通じてテストする方が便利です。もちろん、Swaggerのテストはユニットテストに代わることはできませんが、共同デバッグにおいて非常に重要な効果があります。
4。概要
全体として、Swaggerの構成は比較的簡単であり、ドキュメントを自動的に生成するSwaggerの能力は、実際に多くの作業を節約し、その後のメンテナンスに大きな助けを提供しました。さらに、Swaggerは構成に応じてテストデータを自動的に生成し、対応するHTTPメソッドを提供できます。これは、セルフテストや共同デバッグ作業にも役立ちます。したがって、私はあなたが毎日の開発でSwaggerを使用することをお勧めします。最後に、あなたが考えるために質問を残してみましょう。つまり、ドキュメントにページから直接アクセスできるので、インターフェイスを生産環境、特に外部サービスを提供する必要があるシステムに直接公開することはできません。それでは、どのようにして生産プロセスでこの機能をオフにすることができますか?多くの方法があります、あなたはそれを自分で試すことができます。
上記は、編集者が紹介したSpring Boot Integrated Swagger2プロジェクトの実際の戦闘です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!