Skip to content
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

Allow to specify examples in OpenAPI when skip encode decode body set #2858

Closed
wants to merge 6 commits into from

Conversation

nitinmohan87
Copy link
Contributor

@nitinmohan87 nitinmohan87 commented May 26, 2021

Allows to specify examples for HTTP endpoints with skip request/response encode/decode body as below

                Method("test", func() {
                        Payload(Any, func() {
                               Example("my example")
                        })
                        Result(Any, func() {
                                Example("my result")
                        })
			HTTP(func() {
				POST("/")
				SkipRequestBodyEncodeDecode()
				SkipResponseBodyEncodeDecode()
			})
		})

// SkipRequestBodyEncodeDecode. In this case, we set the request body
// example from the Payload.
req = sf.schemafy(e.MethodExpr.Payload)
}
Copy link
Member

@raphael raphael May 31, 2021

Choose a reason for hiding this comment

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

Should the code remove any header, cookie or param from the payload for the body example?

// it is possible for design to have request Body as Empty and set
// SkipRequestBodyEncodeDecode. In this case, we set the request body
// example from the Payload.
js = sf.schemafy(e.MethodExpr.Result)
Copy link
Member

Choose a reason for hiding this comment

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

Sames as above

Copy link
Member

@raphael raphael left a comment

Choose a reason for hiding this comment

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

Looks good, thank you - I left a few comments and questions

@@ -106,10 +106,10 @@ func basicEndpointSection(m *expr.MethodExpr, svcData *Data) *codegen.SectionTem
MethodData: md,
ServiceVarName: svcData.VarName,
}
if m.Payload.Type != expr.Empty {
if md.Payload != "" {
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain in which cases these two tests are different?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Method Payload can be Empty when SkipRequestEncodeDecode is set. In that case, we should generate the example service correctly without the payload argument.

Copy link
Member

Choose a reason for hiding this comment

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

That makes sense, thank you. Would it make sense/be clearer to use mustInitPayload instead?

for _, r := range httpMet.Responses {
if !r.BodyOnly() {
// one of the response defines header/cookie.
bodyOnly = false
Copy link
Member

Choose a reason for hiding this comment

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

could add a break here

Extensions: openapi.ExtensionsFromExpr(e.Body.Meta),
}}
} else if e.SkipRequestBodyEncodeDecode {
// it is possible for design to have request Body as Empty and set
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand this case. If SkipXXX is used then it seems that the OpenAPI request body schema should be computed by looking up all the attributes of the payload that are not used in headers, cookies and params? If the body type is set to empty then maybe we should honor that in the OpenAPI schema?

// it is possible for design to have response Body as Empty and set
// SkipResponseBodyEncodeDecode. In this case, we set the response body
// example from the Result.
content = make(map[string]*MediaType)
Copy link
Member

Choose a reason for hiding this comment

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

Same as above

})
})
})
}
Copy link
Member

Choose a reason for hiding this comment

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

Do you think we also need to test for the cases where the body has multiple attributes and some are used by other elements than the body (e.g. headers, params etc.)?

httpMet = httpSvc.Endpoint(m.Name)
for _, r := range httpMet.Responses {
if httpMet.SkipResponseBodyEncodeDecode && r.HasBodyOnly() {
return false
Copy link
Member

Choose a reason for hiding this comment

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

Should this function only return false if all responses only define a body?

}
// with SkipResponseBodyEncodeDecode at most one success response can be defined
if r.StatusCode < 400 {
if successResp && e.SkipResponseBodyEncodeDecode {
Copy link
Member

Choose a reason for hiding this comment

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

This a pre-existing bug but it seems the test should also make sure that there is only a body defined (in which case there won't be a result and thus no way for Goa to know what status code to use because no field to test for the Tag value). If there are headers defined then I believe it's OK to have multiple responses.

@@ -536,9 +499,6 @@ func (e *HTTPEndpointExpr) Validate() error {
verr.Add(e, "Payload type is array but HTTP endpoint defines both a body and headers. At most one of these must be defined and it must be an array.")
}
}
if !hasParams && !hasHeaders && e.SkipRequestBodyEncodeDecode {
Copy link
Member

Choose a reason for hiding this comment

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

I don't see this case being covered in the SkipXXX validation functions.

@@ -573,9 +533,6 @@ func (e *HTTPEndpointExpr) Validate() error {
verr.Add(e, "Payload type is map but HTTP endpoint defines both a body and route or query string parameters. At most one of these must be defined and it must be a map.")
}
}
if !hasParams && e.SkipRequestBodyEncodeDecode {
verr.Add(e, "Payload type is map but HTTP endpoint uses SkipRequestBodyEncodeDecode and does not define headers.")
Copy link
Member

Choose a reason for hiding this comment

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

Same as above, I don't see this validation being tested below.

@@ -609,9 +566,6 @@ func (e *HTTPEndpointExpr) Validate() error {
}

body := httpRequestBody(e)
if e.SkipRequestBodyEncodeDecode && body.Type != Empty {
Copy link
Member

Choose a reason for hiding this comment

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

Same as above

}
}
}
if hasResult {
Copy link
Member

Choose a reason for hiding this comment

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

Could that just be in the same block as above?

@@ -1539,7 +1548,7 @@ func buildResponses(e *expr.HTTPEndpointExpr, result *expr.AttributeExpr, viewed
break
}
}
if needInit(result.Type) {
if needInit(result.Type) && !(e.SkipResponseBodyEncodeDecode && resp.HasBodyOnly()) {
Copy link
Member

Choose a reason for hiding this comment

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

Are there cases where we call needInit without testing for SkipResponseBodyEncodeDecode? If not maybe needInit could be refactored to do that test as well?

@github-actions
Copy link

github-actions bot commented Sep 8, 2021

This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions bot closed this Sep 23, 2021
@raphael raphael deleted the add_examples_skip_encode_decode branch June 13, 2022 20:27
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