8000 multiple reponses with different response bodies lead to unexpected result · Issue #412 · cjbooms/fabrikt · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

multiple reponses with different response bodies lead to unexpected result #412

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

Open
AlexanderKomi opened this issue May 2, 2025 · 2 comments

Comments

@AlexanderKomi
Copy link
Contributor
AlexanderKomi commented May 2, 2025

Hi,

Currently I am stuck on an issues regarding responses for different status codes.

I have an api which tries to use ETags to return no response body, if the if-none-match http-header matches an ETag Header on the server.

Unfortunately the API generated by fabrikt does not reflect my intended use-case.

I have the following yaml (abbreviated):

paths:
  '/api/v1/request':
    post:
      parameters:
        - $ref: "#/components/parameters/IfNoneMatch"
        - $ref: "#/components/parameters/CacheControl"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SomeRequest"
      responses:
        "200":
          description: not cached result
          headers:
            ETag:
              $ref: "#/components/headers/ETag"
            Cache-Control:
              $ref: "#/components/headers/CacheControl"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SomeResponse"
        304:
          description: "Returned in conjunction with use of the If-None-Match header.\
            \ Indicates that the resource as described by the passed etag value has\
            \ not changed"
          headers:
            ETag:
              $ref: "#/components/headers/ETag"
            Cache-Control:
              $ref: "#/components/headers/CacheControl"
components:
  parameters:
    CacheControl:
      name: "cache-control"
      in: header
      schema:
        type: "string"
      required: false
      example: "no-cache, public, max-age=5, s-maxage=5"

    IfNoneMatch:
      name: "If-None-Match"
      description: "The RFC7232 If-None-Match header field"
      in: "header"
      schema:
        type: "string"
      required: false

  headers:
    ETag:
      description: "The RFC7232 ETag header field."
      schema:
        type: "string"
      required: false
      example: "W/\"12315154357\""

    CacheControl:
      description: "The RFC7234 Cache Control header"
      schema:
        type: "string"
      required: false
      example: "no-cache, public, max-age=5, s-maxage=5"

  schemas:
    SomeResponse:
      nullable: true
      title: SomeResponse
      type: object
      description: "SomeResponse"
      required:
        - someField
      properties:
        someField:
          description: "someField"
          type: string
          nullable: false
        # ... more fields
    

The gradle script is configured to generate spring controllers with Jakarta for validation.

fabrikt generates the following code (abbreviated):

import jakarta.validation.Valid
import kotlin.String
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Controller
import org.springframework.validation.`annotation`.Validated
import org.springframework.web.bind.`annotation`.RequestBody
import org.springframework.web.bind.`annotation`.RequestHeader
import org.springframework.web.bind.`annotation`.RequestMapping
import org.springframework.web.bind.`annotation`.RequestMethod

@Controller
@Validated
@RequestMapping("")
public interface ApiV1RequestController {
  /**
   *
   * ...
   * @param someRequest
   * @param ifNoneMatch The RFC7232 If-None-Match header field
   * @param cacheControl 
   */
  @RequestMapping(
    value = ["/api/v1/request"],
    produces = ["application/json", "application/json"],
    method = [RequestMethod.POST],
    consumes = ["application/json"],
  )
  public fun request(
    @RequestBody @Valid someRequest: SomeRequest,
    @RequestHeader(value = "If-None-Match", required = false) ifNoneMatch: String?,
    @RequestHeader(value = "cache-control", required = false) cacheControl: String?,
  ): ResponseEntity<SomeResponse>
}

The generated response type is not nullable, although the response for http 403 must not return a body.
Is there any way to work around this problem?

@ulrikandersen
Copy link
Collaborator

The controller generators consider only the happy path, as seen for Spring here.

It would be a nice addition if we can support all the response cases.

I think first step could be to come up with a format for the generated code that will allow the user to respond with the different statuscode-reponsetype combinations.

@cjbooms
Copy link
Owner
cjbooms commented May 3, 2025

Yep, use exceptions to drive the non happy path response types.

However, maybe the problem here is fabrikt isn't taking the nullable: true into account in the response schema.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
0