Ash - I'd really love to see your example extended to handle dynamic objects:
a) conf : { "x": 34 } b) conf: { "a": [1, 2, 3] } c) conf: { "Z": [1,2], "W": "a" } Without having to recompile the java client every time a new structure of conf is added. J, On Fri, May 29, 2020 at 10:13 PM Ash Berlin-Taylor <a...@apache.org> wrote: > Responses inline > > > > > On May 29 2020, at 5:49 pm, Jarek Potiuk <jarek.pot...@polidea.com> wrote: > > > > From what I understand - that single choice prevents our customers to > > use auto-generation in many languages > > = reasons for that explained by Kamil). Here are few examples: > > > > * Typescript: > https://www.gitmemory.com/issue/OpenAPITools/openapi-generator/4119/540506783 > > > * Java: https://github.com/OpenAPITools/openapi-generator/issues/2037 > > This issue has been fixed for over a year. > > > * REST client for JIRA (not sure which language) : > > > https://community.developer.atlassian.com/t/jira-rest-client-generation-fails-swagger-open-api-generator/36398 > > > * GO: > https://medium.com/real-apis/free-form-objects-with-array-values-72e85c044e4a > > Talks very specificazlly about Arrays, not objects, so I don't think > this applies. > > > > > The problem is that the right code cannot be generated for those > > languages for freeForm > > unless you specify "additionalProperties" field which will tell at > > least what types the keys and values > > have. Which we cannot do in our case. > > `additionalProperties: true` is supported by the OpenAPI spec to say > "anything else is allowed. > > > > > > Unless someone proves that we can generate automatically, usable > > clients in those > > languages automatically this one will be vetoed from my side. > > > Using's Kamil's generated Java client (with deleting the broken > references to OneOfScheduleInterval as it isn't relevant to this point), > my same Employee example from earlier. > > > import org.openapitools.client.JSON; > > ... > > @Test > public void confTest() { > // TODO: test conf > // > Employee employee = new DAGRunTest.Employee(1, "Ash", > "Berlin-Taylor"); > model.setConf(employee); > > Assert.assertEquals(new JSON().serialize(model), > > "{\"external_trigger\":true,\"conf\":{\"id\":1,\"firstName\":\"Ash\",\"lastName\":\"Berlin-Taylor\"}}"); > } > > That passes. So it's trivially easy on the setting side. Working out the > reading deser. side now. > > -ash > > > > > > I think the ease-of-use and the Open API specification we have is to > > make it possible > > for the users to use the API easily. but in this case, by one line > > decision we are basically > > forcing our users to hand-write their whole code > > instead of generating it all because of one "FreeForm" object in the API. > > > > I don't think there is a lot of empathy to our users if we make this > decision. > > To be honest I see it as a bit selfish decision (if what I understand > > is correct). > > > >> The first one means technically, acording to the spec you can submit `{ > >> "conf": "abc" }` -- but that will fail. Where as the second means that > >> both the OpenAPI client, and the automatic validation from Connexion on > >> the server will handle that for us. > > > > Not fully really because in at least few languages the OpenAPI client > > - and validation - > > will have to be manually written anyway. > > > >> (With the string case, we would have to JSON deserialize it and check > >> it's an JSON object/ python dict. Nothing else is allowed.) > > > > Yeah. Now that we know that it's not allowed we know it needs to be > dictionary. > > Indeed - we will have to validate that ourselves. There is no > > performance loss though > > more security (open API has to do it anyway while parsing for "object > > type" and does not > > have to do it for string) > > > > As I've written before - the only real validation of the data is done > > by the > > DAG reading the values. Nothing prevents the user from sending { "a": > > {"b" : [] } }, > > when dag expects {"a": "b"}. We cannot *really* validate the data with > > Open API. > > > > And I think single `isinstance(json.loads(conf),dict)` is far, far, far > > much easier to write than hand-coding your client class instead of > > generating it. > > > > As I see it now in this case, the real trade-off we are dealing with > > here is: > > > > * "should we add this line of code to validate" vs. > > * "should we make our users suffer and spend extra xx days to write > their > > client libraries instead of generating them". > > > >> To use your example DagRun class, the signature could become: > >> > >> public DagRun(String dagRunId, String executionDate, Object conf); > >> > >> and then the client can do `gson.toJsonTree(conf).getAsJsonObject()` > internally. > > > > Actually - It does not work that easily with the dynamic Objects and > > structure of the objects. > > If you want to pass conf as the conf object to the class and get it > working > > as you described, you will have to define a separate class for EVERY > > TYPE of conf object > > that you pass to different DAG and know which of the Type object > > should be passed > > to the DagRun constructor. > > > > This basically means that if you have two DAGs with two different set > > of config parameters you need to define > > different Class for each DAG and know which class shoudl be passed to > > the constructor > > Basically this means that the users will have to develop, recompile > > and release Java client > > every time they add a new DAG that might require some configuration. > > > > With the string solution the natural thing will be that conf is > > hand"coded" and generated dynamically rather > > then recompiled as a new Java class. > > > > And you have not shown how you would convert the "client" case I > > mentioned where you specify the conf object > > via command line as string. How would you decide which class to use? > > Based on what? How do you know > > which DAG is which conf class? I think this is a really difficult one > > to pull by the client if they use > > statically typed language like Java. > > > >> JSON-encoded-string in a JSON api is a "code smell" to me. > > > > I think we are giving our static language client users much more than > > a "smell" here. > > > -- Jarek Potiuk Polidea <https://www.polidea.com/> | Principal Software Engineer M: +48 660 796 129 <+48660796129> [image: Polidea] <https://www.polidea.com/>