Open dvgica opened 4 years ago
I think allowing x-jvm-package
there would be a good idea. This would also be good motivation to thread fully qualified names through to more places; just referring to it by its FQN would be safer and more reliable than playing import juggling games.
Scenario
Suppose I have two APIs, each with their own OpenAPI spec
apples.yaml
andoranges.yaml
. They are both fed to Guardrail to generate routes and models in the same project, but using differentScalaServer
instances with different packages (saycom.example.apples
andcom.example.oranges
).While they are mostly unrelated APIs and deserve separate specs, they share some definitions, e.g.
Foo
. In OpenAPI, we can put those definitions incommon.yaml
and then reference them from the specs using$ref: "common.yaml#/definitions/Foo"
.Guardrail handles this scenario by generating both
com.example.apples.definitions.Foo
andcom.example.oranges.definitions.Foo
. This works OK-ish until you want to write some common code aroundFoo
, and have to deal with both types. In reality, there should only be oneFoo
type, used by both APIs.I haven't found a great way to deal with this, but maybe I'm missing something. What I would like is for there to be a
com.example.common.definitions.Foo
that can be referenced in either API.Current Workaround
Right now I'm using a separate
ScalaModels
instance to buildcommon.yaml
, this yieldscom.example.common.definitions.Foo
. I then prevent Guardrail from generatingcom.example.apples.definitions.Foo
andcom.example.oranges.definitions.Foo
by purposefully breaking the OpenAPI reference: changing$ref: "common.yaml#/definitions/Foo"
to$ref: "<common_file>#/definitions/Foo"
. Guardrail saysUnable to find definition for Foo, just inlining
and carries on. Finally, I use an extra import on the apples/orangesScalaServer
to addcom.example.common.definitions._
, providing the singleFoo
definition to the APIs.This is a bit of a hack. It requires that I do some text processing on the API specs to replace
<common_file>
withcommon.yaml
before the specs can be used by other OpenAPI tooling.Other Options
I considered generating the
apples
andoranges
code in the same package. This would result in a singleFoo
definition I think. It's a bit messy, since they're unrelated, but more importantly, it doesn't protect against model name conflicts, for example if both APIs define a non-commonBar
model, this won't work.Possible Solution?
What I really want to do is dictate that a definition should be generated in a package separate from the API routes. What if
x-jvm-package
was allowed ondefinitions
? Then incommon.yaml
I could have:And it would only be generated once. It would still be up to me to add the extra import to my
ScalaServer
s, or I suppose Guardrail could do this automatically if we wanted to get fancy.But, I'm very open to other ideas, and also hoping that there's already a way to do this that I missed.