2017-10-12 5 views
0

私の質問はposted hereに関連しています。レスポンスエンティティをマスターテンプレートレスポンスで囲むにはどうすればいいですか?

私は以前のものがあまりにも冗長であると感じたので、私の質問を言い換える必要がありました。もう一度やってみよう!

私は資産のリストを返すREST APIを持っており、それは次のようにコーディングされています:

@GET 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getAllAssets() { 
     List<Asset> assets = new ArrayList<Asset>(); 
     for(int i=1; i<11; i++) { 
      assets.add(new Asset(i)); 
     } 

     return RestResponse.create(Status.OK, "10 assets Fetched successfully!", assets); 
    } 

が生成する応答は、このようなものです:私は60以上のサービスを持っている

{ 
    "message":"10 assets Fetched successfully!", 
    "content": [{ 
     "id":"1", 
     "type":"LPTP", 
     "owner":"Ram", 
     "serialNo":"WDKLL3234K3", 
     "purchasedOn":"01 Jan 2017" 

    }, 
    { 
     "id":"2", 
     "type":"LPTP", 
     "owner":"Ram", 
     "serialNo":"WDKLL3234K3", 
     "purchasedOn":"01 Jan 2017" 

    }, 
    ... 
    ] 
} 

私のアプリケーションでは、同じ応答テンプレートに従います:

{ 
     "message":"Message the service wants to send to the client", 
     "content": { 
      .... 
      Entity returned by the service 
      .... 
     } 
} 

以下は残りの部分です私たちの応答テンプレートを表しレスポンスPOJO:

public class RestResponse { 
     private String message; 
     private Object content; 

     public String getMessage() { 
      return message; 
     } 
     public void setMessage(String message) { 
      this.message = message; 
     } 
     public Object getContent() { 
      return content; 
     } 
     public void setContent(Object content) { 
      this.content = content; 
     } 

     private RestResponse(String message, Object content) { 
      this.message = message; 
      this.content = content; 
     } 

     public static Response create(Response.Status status, String message, Object content) { 
      return Response.status(status).entity(new RestResponse(message, content)).build(); 
     } 
} 

今、私たちは、闊歩を使用して、すべての私たちのAPIを文書化している、と問題に遭遇してきました。

我々はすべて私たちのAPIのRestResponseクラスを返しているので、私は自分の操作のために、以下の注釈を書いた:

@ApiOperation(value="Fetches all available assets", response=RestResponse.class, responseContainer="List") 

、RestResponseクラスの定義スキーマに次のようになりますされない何を闊歩:ここで

"definitions": { 
    "RestResponse": { 
     "type": "object", 
     "properties": { 
     "message": { 
      "type": "string" 
     }, 
     "content": { 
      "type": "object" 
     } 
     } 
    } 
} 

、私はcontentプロパティ内のオブジェクトのプロパティに関する情報やスキーマを得ることはありません。

スワッガーは汎用オブジェクトでは動作しないためです。

私は、以下のいずれかに私の@ApiOperation注釈を変更するのであれば:上記の場合

@ApiOperation(value="Fetches all available assets", response=Asset.class, responseContainer="List") 

、闊歩はAssetエンティティのプロパティを説明したが、明らかに(私の応答テンプレートの)、message財産、不足している。

私の問題は両方を持ちたいということです。私の応答テンプレートのcontentプロパティは任意のエンティティにすることができます。

response=Asset.classを設定し、文書化する前にAssetRestResponsecontentのプロパティに囲むように指示することはできますか?それとも私がこれを達成できる他の方法?

今回は正確ですね!

ありがとう、 Sriram Sridharan。

編集 - 私はマルク・ヌリの提案 を試してみた後、私は一般的なオブジェクトと同様のRestServiceResponse.classを作成し、そして私の@ApiOperationRestServiceResponse<Asset>のためresponseReference属性を設定します。下にJSONがあります。

{ 
    "swagger": "2.0", 
    "info": { 
    "version": "1.0.0", 
    "title": "" 
    }, 
    "host": "localhost:7070", 
    "basePath": "/assets/rest", 
    "tags": [ 
    { 
     "name": "Assets" 
    } 
    ], 
    "schemes": [ 
    "http" 
    ], 
    "paths": { 
    "/assets/{id}": { 
     "get": { 
     "tags": [ 
      "Assets" 
     ], 
     "summary": "Fetches information about a single asset", 
     "description": "", 
     "operationId": "fetchAssetDetail", 
     "produces": [ 
      "application/json" 
     ], 
     "parameters": [ 
      { 
      "name": "id", 
      "in": "path", 
      "required": true, 
      "type": "integer", 
      "format": "int32" 
      } 
     ], 
     "responses": { 
      "200": { 
      "description": "successful operation", 
      "schema": { 
       "$ref": "#/definitions/RestServiceResponse<Asset>" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

ご覧のとおり、Definitionsセクションは完全に欠落しています。何か不足していますか?

コード全体を確認する必要がある場合は、project in GitHubを持っています。私を助けてください。

答えて

0

もう一度、Marc Nuri!

私のシナリオでうまくいく解決策を見つけたかもしれません。ここに私がしたことがあります。私は私の質問で述べた1(最新の編集)と同じように私RestServiceResponseクラスを持っている、と私はちょうどこのようstatic final classを追加することにより、AssetServiceクラスによって変更:

private static final class AssetResponse extends RestServiceResponse<Asset> { 
     private Asset data; 
} 

これが完了すると、私は変更しました私@ApiOperationこれに注釈:

@ApiOperation(value="Fetches an asset by ID", produces="application/json", response=AssetResponse.class) 

さて、これは基本的にされて何をするか、純粋なドキュメントの目的のために、それだけでコンパイル時に特定のAssetタイプとRestServiceResponseクラスにジェネリック型を置き換えるようだ、闊歩するようにオブジェクトを定義できます。

私はswagger JSON URLを実行したとき、私は完璧なドキュメントを手に入れました!

{ 
    "swagger": "2.0", 
    "info": { 
    "version": "1.0.0", 
    "title": "" 
    }, 
    "host": "localhost:7070", 
    "basePath": "/assets/rest", 
    "tags": [ 
    { 
     "name": "Assets" 
    } 
    ], 
    "schemes": [ 
    "http" 
    ], 
    "paths": { 
    "/assets/{id}": { 
     "get": { 
     "tags": [ 
      "Assets" 
     ], 
     "summary": "Fetches information about a single asset", 
     "description": "", 
     "operationId": "fetchAssetDetail", 
     "produces": [ 
      "application/json" 
     ], 
     "parameters": [ 
      { 
      "name": "id", 
      "in": "path", 
      "required": true, 
      "type": "integer", 
      "format": "int32" 
      } 
     ], 
     "responses": { 
      "200": { 
      "description": "successful operation", 
      "schema": { 
       "$ref": "#/definitions/AssetResponse" 
      } 
      } 
     } 
     } 
    } 
    }, 
    "definitions": { 
    "Asset": { 
     "type": "object", 
     "required": [ 
     "name", 
     "owner", 
     "purchaseDate", 
     "type" 
     ], 
     "properties": { 
     "id": { 
      "type": "integer", 
      "format": "int32", 
      "description": "The internal unique ID of the Asset" 
     }, 
     "name": { 
      "type": "string", 
      "description": "Name of the asset" 
     }, 
     "type": { 
      "type": "string", 
      "description": "Name of the asset", 
      "enum": [ 
      "Laptop", 
      "Desktop", 
      "Internet Dongle", 
      "Tablet", 
      "Smartphone" 
      ] 
     }, 
     "owner": { 
      "type": "string", 
      "description": "ID of the person who owns this asset" 
     }, 
     "purchaseDate": { 
      "type": "string", 
      "format": "date", 
      "description": "Date when this asset was purchased" 
     } 
     } 
    }, 
    "AssetResponse": { 
     "type": "object", 
     "properties": { 
     "message": { 
      "type": "string" 
     }, 
     "content": { 
      "$ref": "#/definitions/Asset" 
     } 
     } 
    } 
    } 
} 

これが最も効率的な解決策であるかどうかはまだ分かりませんが、今はボールを転がすのに十分です。アイデアを教えてください。

0

私たちはマイクロサービスの対応において同様の構造を使用しています。

唯一の違いは、Googleのレスポンスコンテナ(つまりRestResponse)には生のタイプがなく、メッセージの本文/コンテンツにタイプパラメータが使用されている点です。そして、このようなあなたのエンドポイントに注釈を付ける

public class RestResponse<T> { 
    private String message; 
    private T content; 

    public String getMessage() { 
     return message; 
    } 
    public void setMessage(String message) { 
     this.message = message; 
    } 
    public T getContent() { 
     return content; 
    } 
    public void setContent(T content) { 
     this.content = content; 
    } 

    private RestResponse(String message, T content) { 
     this.message = message; 
     this.content = content; 
    } 

    public static <T> Response create(Response.Status status, String message, Object content) { 
     return Response.status(status).entity(new RestResponse(message, content)).build(); 
    } 
} 

@ApiOperation(
      value="Fetches all available assets", 
      responseReference = "RestResponse<List<Asset>>") 

これが闊歩の最新バージョンOK取り組んでいる

にごRestResponseを変更してみてください。

+0

こんにちは@MarcNuri、私はあなたの提案を試しましたが、それでも多かれ少なかれ同じ問題に直面しています。私を助けてもらえますか?私は詳細で質問を編集しました。 – sriramsridharan

+0

こんにちは。私たちのプロジェクトでは、swagger-uiでSpringとSwagger2を使用しています。たぶんそれは違う振る舞いをしているのかも私が解決策で説明したことは、Swaggerのライブラリのドキュメントには書かれていませんが、動作しています。 あなたのコードをチェックして、何が起こっているのかを確認します。 –

関連する問題