Skip to content

core: implement a oneOfInput - #5591

Draft
hughsimpson wants to merge 8 commits into
softwaremill:masterfrom
hughsimpson:OneOfInput
Draft

hughsimpson wants to merge 8 commits into
softwaremill:masterfrom
hughsimpson:OneOfInput

Conversation

@hughsimpson

@hughsimpson hughsimpson commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Implements a oneOfInput, analogous to the oneOf output method, but for inputs; this aids in client selection of a variant, and in representing some optional request bodies. The existing oneOfBody currently only works for invariant type params on the variants, and coerces the client to only send the first variant, which may not always be desired. The new approach basically just works the same way as the output variants -- perform the api selection according to the matcher. I think this goes somewhat in the direction of addressing #4971 ?

I'm not sure if this is the best idea... This spun out of #5592, and the specific issue I was trying to address here is for the codegen implementation: optional request bodies generally work fine with a jsonBody[Option[T]] representation, but for some other types there doesn't seem to ba an available to way to implement optionality that doesn't involve some unsoundness (e.g. stringJsonBody.map(Option(_))(_.orNull)) or something 'cleverer' that needs to become aware of the underlying representation (e.g stringJsonBody.map(Some(_).filter(_.nonEmpty))(_.getOrElse(""))). The justification for a more general approach is that I can kinda imagine we might not always want to pick the first client req option anyway -- for example, we can imagine an endpoint

set-profile-picture:
  put:
      requestBody:
        required: true
        content:
          application/json:
            $ref: '#/components/schemas/LinkToExistingImage'
          image/png:
            type: string
            format: binary

where even though the body is required, the client does want to be able to discriminate between what it sends. This might not be a good API, but it is a valid api so should be achievable and I don't think the client could achieve that previously...? (Edit: a more defensible motivating design might be wanting to upload different binary types from a client without needing a ../xml suffix or whatever on the endpoints, just using some subtype to discriminate on what content-type to set)

As far as compatibility goes, this is adding a variant to a sealed trait so it's a bit of a thing, but probably only a minor version bump according to MiMa?

Full disclosure: the code in this pr was driven a fair bit by cursor... welcome to 2026 I guess 😅 If this is deemed a sensible way of addressing the issue, then I can go through and tidy up the slop comments etc, but I didn't want to spend too much time going in this direction if I was barking up the wrong tree.

@hughsimpson
hughsimpson marked this pull request as ready for review October 12, 2026 11:01
@hughsimpson hughsimpson changed the title implement a oneOfInput core: implement a oneOfInput Oct 13, 2026
@hughsimpson
hughsimpson marked this pull request as ready for review October 13, 2026 08:46
@hughsimpson

hughsimpson commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

@adamw this is ... Not my best work. I'm happy to go through and clean up I just want to gauge whether it's a good way to go, and what you'd want from it for it to be landable. I can see a couple of places that we can at least de-slop the comments, for example; and the api doesn't exactly feel consistent with prior art. But if you think the idea is a bunk, I'm not gonna want to spend more time on it 😅

@hughsimpson

hughsimpson commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

I'm gonna re-mark this as draft lest you think less of me, but I suspect I really won't be taking this further without feedback; and I really can't think of another way to represent the apis in the example case. I feel terrible leaving you to consider something that's barely felt the hand of a human, but... Look, hopefully the intent is clear enough

@hughsimpson
hughsimpson marked this pull request as draft October 13, 2026 20:30
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

Successfully merging this pull request may close these issues.

1 participant