Skip to content

[Spring] Add an option to return success code #1197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Nov 29, 2018

Conversation

ackintosh
Copy link
Contributor

@ackintosh ackintosh commented Oct 8, 2018

PR checklist

  • Read the contribution guidelines.
  • Ran the shell script under ./bin/ to update Petstore sample so that CIs can verify the change. (For instance, only need to run ./bin/{LANG}-petstore.sh and ./bin/security/{LANG}-petstore.sh if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates). Windows batch files can be found in .\bin\windows\.
  • Filed the PR against the correct branch: master, 3.4.x, 4.0.x. Default: master.
  • Copied the technical committee to review the pull request if your PR is targeting a particular programming language.

Description of the PR

This PR makes the stub server returns status code defined at Response Object instead of 501(Not implemented).

This PR adds an option to make the stub server return success code. ( #1197 (comment) )

Remove the spacer "{{#async}} ... {{/async}}" "{{^async}} ... {{/async}}"
@ackintosh
Copy link
Contributor Author

@bbdouglas (2017/07) @JFCote (2017/08) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01)

ApiUtil.setExampleResponse(request, "application/xml", "<Order> <id>123456789</id> <petId>123456789</petId> <quantity>123</quantity> <shipDate>2000-01-23T04:56:07.000Z</shipDate> <status>aeiou</status> <complete>true</complete></Order>");
break;
}
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad indent

{{#jdk8}}
{{#async}}
{{#-first}}
{{#jdk8}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is broken

@cbornet
Copy link
Member

cbornet commented Oct 8, 2018

I'm not sure about this one : why would we pick a specific status code over another ?
At least 501 describes the situation quite well : the endpoint was not implemented yet.

@ackintosh
Copy link
Contributor Author

Thanks for your review!
I'm considering that the case of frontend development (e.g. SPA, mobile app) with a stub server.
In that case, a stub server returns a value defined at spec, but a client interprets the response as an error as the response code is 501.

@cbornet
Copy link
Member

cbornet commented Oct 9, 2018

Then I guess you would rather have a 200 for all endpoints in that case, no ?

@cbornet
Copy link
Member

cbornet commented Oct 9, 2018

We could have an application property where you set the default HTTP code you want to get.

@ackintosh
Copy link
Contributor Author

The following is the spec that I'm working on. The each endpoint differently have the HTTP code a stub server should returns. (GET /posts -> 200, DELETE /posts/{postId} -> 204)
So I think we need to pick a specific status defined at responses.

openapi: 3.0.1
info:
  title: 匿名掲示板API
  version: 1.0.0
paths:
  /posts:
    get:
      description: 投稿をすべて取得する
      responses:
        '200':
          description: 投稿の配列
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Post'
    post:
...
      responses:
        '201':
          description: 作成した投稿
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Post'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
  /posts/{postId}:
    delete:
      description: 投稿を削除する
      parameters:
        - $ref: '#/components/parameters/postIdParam'
      responses:
        '204':
          description: 投稿の削除に成功
        '404':
          $ref: '#/components/responses/NotFound'
...

@cbornet
Copy link
Member

cbornet commented Oct 9, 2018

Is it really important for your client ? Clients should accept any 2xx codes as successful responses (as per Postel's law)

@ackintosh
Copy link
Contributor Author

As you say from the view of client, it may not important. Client can accept 2xx codes as successful responses.
On the other hand, from the view of a stub server, I think we should return properly codes as possible as.

@cbornet
Copy link
Member

cbornet commented Oct 9, 2018

Ok. Then we would need some kind of "success code" resolution. I wonder if we don't already have that for some gens.

@ackintosh
Copy link
Contributor Author

I've fixed the broken indentation. Please have a look when you have time.

@ackintosh
Copy link
Contributor Author

ping @cbornet 😉

@cbornet
Copy link
Member

cbornet commented Oct 26, 2018

I still think we shouldn't send codes like 400 by default. As I see it, OAI response codes are mostly hints for special codes that you want to highlight. We could however do something smarter about 2xx codes. But in any case sending a successful or not 5xx error code should be at most an option (not necessarily at generation, could be an app option).

@@ -1,35 +1,38 @@
{{^reactive}}
int statusCode = {{#responses}}{{#-first}}{{{code}}}{{/-first}}{{/responses}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be inlined in the ResponseEntity which would make the PR much simpler.

@ackintosh
Copy link
Contributor Author

I still think we shouldn't send codes like 400 by default. As I see it, OAI response codes are mostly hints for special codes that you want to highlight.

That's a thought.


I've noticed two use cases of the generated server codes:

  1. Scaffolding
  1. Just for stubbing
  • The use case mentioned in this comment.
  • The generated codes are used for just stubbing in frontend development.
    • When server-side development has finished the stub is replaced with the concrete application.
    • This contract-first approach proceeds frontend and server-side parallely
  • In this use case the generated server should return a status code defined in the OpenAPI spec.
    • I think 400 is not problem in this use case if 400 is defined at the spec.
    • If 500/400 is inconvenient we can put 200 at top of responses definition.

@cbornet
Copy link
Member

cbornet commented Nov 15, 2018

Yes, for scaffolding 501 is better, for stubbing I guess 2xx would be better with resolution of the code if there are codes different than 200 defined in the OAI.

@ackintosh
Copy link
Contributor Author

for stubbing I guess 2xx would be better with resolution of the code if there are codes different than 200 defined in the OAI.

Good idea. 💡

👇In my mind, mustache file will be updated like below. Are we on the same page?

MethodBody.mustache

-    return new ResponseEntity<>(HttpStatus.valueOf(HttpStatus.NOT_IMPLEMENTED));
+    return new ResponseEntity<>(HttpStatus.valueOf(
+        ({{#responses}}{{#-first}}{{{code}}}{{/-first}}{{/responses}} >= 400) ? 200 : {{#responses}}{{#-first}}{{{code}}}{{/-first}}{{/responses}}
+    ));

@cbornet
Copy link
Member

cbornet commented Nov 16, 2018

I think we could do the resolution in the Java gen (postProcessOperation ?)

@ackintosh
Copy link
Contributor Author

Ah 💡 Thanks!

* Revert "Fix broken indentation"
  * This reverts commit 95b6a00.
* Revert "Tweak indent"
  * This reverts commit ba2cedc.
* Revert "Returns status code which defined at Response Object"
  * This reverts commit f676a89.
@ackintosh
Copy link
Contributor Author

Hmm... ideally example should have its status code. example has its "content-type" and "response body".
(related class: ExampleGenerator.java)

op.examples = new ExampleGenerator(schemas, openAPI).generateFromResponseSchema(responseSchema, getProducesInfo(openAPI, operation));
String exampleStatusCode = "200";
for (String key : operation.getResponses().keySet()) {
if (operation.getResponses().get(key) == methodResponse && !key.equals("default")) {
Copy link
Contributor Author

@ackintosh ackintosh Nov 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

methodResponse is "2xx" or "default" so exampleStatusCode will be 2xx.

@ackintosh ackintosh force-pushed the return-status-code-properly branch from dc7087a to bd7ee46 Compare November 18, 2018 03:13
@ackintosh
Copy link
Contributor Author

Please review the changes when you have time. 🙏

@ackintosh
Copy link
Contributor Author

As be commented at gitter, I'll make this changes an option. Making the changes an option makes sense to preserve backward compat and covers the two use cases.

cc @cbornet

@ackintosh
Copy link
Contributor Author

We have 2 ways how make the changes an option: Generation or Spring config. I'm trying to make a "Generation" option as I'm not familiar with Spring. 🤔💦

@ackintosh ackintosh changed the title [Spring] Return status code properly [Spring] Add an option to return success code Nov 28, 2018
@ackintosh
Copy link
Contributor Author

Changed the PR title.

@ackintosh
Copy link
Contributor Author

ackintosh commented Nov 28, 2018

Test --additional-properties returnSuccessCode=true

$ bin/springboot-petstore-server.sh --additional-properties returnSuccessCode=true
...
...
$ git diff

↓↓

image

@ackintosh
Copy link
Contributor Author

@cbornet I've updated this PR, make success code optional. Generated server returns 501 as default. Please review 🙏

@@ -25,14 +25,14 @@ return CompletableFuture.supplyAsync(()-> {
{{/-last}}
{{/examples}}
{{^examples}}
return {{#jdk8}}{{#async}}CompletableFuture.completedFuture({{/async}}{{/jdk8}}new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED){{#jdk8}}{{#async}}){{/async}}{{/jdk8}};
return {{#jdk8}}{{#async}}CompletableFuture.completedFuture({{/async}}{{/jdk8}}new ResponseEntity<>({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}}){{#jdk8}}{{#async}}){{/async}}{{/jdk8}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be HttpStatus.valueOf({{{statusCode}}}) instead of HttpStatus.OK

@@ -43,5 +43,8 @@ exchange.getResponse().setStatusCode(HttpStatus.NOT_IMPLEMENTED);
}
{{/-last}}
{{/examples}}
{{^examples}}
exchange.getResponse().setStatusCode({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be HttpStatus.valueOf({{{statusCode}}}) instead of HttpStatus.OK ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should be HttpStatus.OK as the status code is contained by example. The code above is in {{^examples}} section.

@cbornet
Copy link
Member

cbornet commented Nov 28, 2018

LGTM 👍

@ackintosh
Copy link
Contributor Author

Thank you. ✨

@ackintosh
Copy link
Contributor Author

To be clear the purpose, I've updated the description of this PR. 😌
#1197 (comment)

@ackintosh ackintosh merged commit f7c857c into OpenAPITools:master Nov 29, 2018
@ackintosh ackintosh deleted the return-status-code-properly branch November 29, 2018 02:51
A-Joshi pushed a commit to ihsmarkitoss/openapi-generator that referenced this pull request Feb 27, 2019
* Returns status code which defined at Response Object

* Tweak indent

Remove the spacer "{{#async}} ... {{/async}}" "{{^async}} ... {{/async}}"

* Update samples^

* Fix broken indentation

* Update samples

* Revert methodBody.mustache

* Revert "Fix broken indentation"
  * This reverts commit 95b6a00.
* Revert "Tweak indent"
  * This reverts commit ba2cedc.
* Revert "Returns status code which defined at Response Object"
  * This reverts commit f676a89.

* Example contains status code

* Update samples

./bin/spring-all-pestore.sh

* Fix syntax error

* Update samples

* Run bin/utils/ensure-up-to-date

* Make the changes an option `returnSuccessCode`

* Run bin/spring-all-pestore.sh to update samples

* Run ./bin/utils/export_docs_generators.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants