Open pontus-eliason opened 2 years ago
Welcome to OpenRPC! Thank you for taking the time to create an issue. Please review the guidelines
@pontus-eliason firstly, I want to commend you for the great use of spec extensions!
I think you are on the right track with this. One thing that comes to mind that you could try is to run a pre-processing step on your openrpc document which would remove the x-interface
key and in turn, add in the params to all the required places.
for example, if you start with
{
methods: [{
method: "foo",
params: [
{
"name": "X",
"required": true,
"schema": {
"$ref": "#/components/schemas/X"
}
}
],
result: [],
x-extend-params: ["CredentialProperties"]
}],
components: {
contentDescriptors: {
username: {
"name": "Username",
"required": true,
"schema": {
"$ref": "#/components/schemas/Username"
},
"x-interface": "CredentialProperties"
},
{
"name": "Password",
"required": true,
"schema": {
"$ref": "#/components/schemas/Password"
},
"x-interface": "CredentialProperties"
}
}
}
then you'd run your spec extension pre-processor and get back:
{
methods: [{
method: "foo",
params: [
{"$ref": "#/components/contentDescriptors/Username"},
{"$ref": "#/components/contentDescriptors/Password"},
{
"name": "X",
"required": true,
"schema": {
"$ref": "#/components/schemas/X"
}
}
],
result: [],
x-extends-interface: ["CredentialProperties"]
}],
components: {
contentDescriptors: {
username: {
"name": "Username",
"required": true,
"schema": {
"$ref": "#/components/schemas/Username"
},
"x-interface": "CredentialProperties"
},
{
"name": "Password",
"required": true,
"schema": {
"$ref": "#/components/schemas/Password"
},
"x-interface": "CredentialProperties"
}
}
}
once running through codegen, you would (presumably) get the same resulting interfaces.
Another similar approach would be to use root-level vendor extension, and create your own abstraction around applying content descriptors to specific methods, and once again, run a preprocessor on it.
If for whatever reason pre-processing is not an option, then you would need tooling to support your specification extension, or have a plugin/extension interface allowing you to add code to handle your extension.
Hopefully that helps.
You could also have your specification extension make use of tags
in order to group methods based on what interfaces they extend from. Then you would only need the 1 field x-interface
which matches contentDescriptors with the methods that they should be added to.
Something to consider: when params is byPosition (method expects an array), you would need a way to specify the order in which the params should be added/extended/inherited (what ever you wanna call that =p).
Hi!
For our methods, we have multiple common params for each method, let's call them
Username
andPassword
. So if we have 100 methods, we are for each one required to write:I tried to conjure up some make-believe kind of schema that could solve this, but I'm actually stumped. Because it seems very difficult to do, since the params must be an array, and the inheritance through some sort of
allOf
quickly becomes clumsy.I need this for quite a simple reason: When we generate code from the specification, it would greatly help to be able to say "All request params follow this interface containing Username and Password".
The only current solution I've been able to think of is to do something like this using specification extensions:
And then alter the code generation logic in a way that makes the 2 properties be added to a custom interface, so when we receive it on the server end (in Java) we get a class
RequestX
which implements interfaceCredentialProperties
.Is there a better way of doing this?