Cool! thanks QP! Seems that the change to allOf instead of oneOf does the trick also for Java.
And I did a quick test using the same mechanism that the generated APIs use and it seems that all my cases can be easily handled when "object" is used. Both writes and reads work as expected. It's very easy to get any object as conf providing generic HasMap as conf - it's also equally easy to build the HashMap from string for arbitrary objects. In this case I am perfectly fine with using "object". @Test public void dagTest() throws IOException { DAGRun dagRun = new DAGRun(); HashMap<Object, Object> confObject = new HashMap<>(); String array[] = new String[] {"1", "2", "3"}; confObject.put("a", array); confObject.put("b", "c"); dagRun.setConf(confObject); ObjectMapper mapper = api.getApiClient().getObjectMapper(); String data = mapper.writer().writeValueAsString(dagRun); System.out.println(data); TypeReference<DAGRun> typeRef = new TypeReference<DAGRun>() {}; DAGRun dagRunRead = mapper.readValue(data, typeRef); System.out.println(); System.out.println(dagRunRead); System.out.println(dagRunRead.getConf().getClass()); DAGRun dagRun2 = new DAGRun(); HashMap confObject2 = mapper.readValue("{\"a\":[\"1\", \"2\", \"3\"],\"b\":\"c\" }", confObject.getClass()); dagRun2.setConf(confObject2); String data2 = mapper.writer().writeValueAsString(dagRun2); System.out.println(data2); DAGRun dagRunRead2 = mapper.readValue(data, typeRef); System.out.println(); System.out.println(dagRunRead2); System.out.println(dagRunRead2.getConf().getClass()); } Produces: "dag_run_id":null,"dag_id":null,"execution_date":null,"start_date":null,"end_date":null,"state":null,"external_trigger":true,"conf":{"a":["1","2","3"],"b":"c"}} class DAGRun { dagRunId: null dagId: null executionDate: null startDate: null endDate: null state: null externalTrigger: true conf: {a=[1, 2, 3], b=c} } class java.util.LinkedHashMap {"dag_run_id":null,"dag_id":null,"execution_date":null,"start_date":null,"end_date":null,"state":null,"external_trigger":true,"conf":{"a":["1","2","3"],"b":"c"}} class DAGRun { dagRunId: null dagId: null executionDate: null startDate: null endDate: null state: null externalTrigger: true conf: {a=[1, 2, 3], b=c} } class java.util.LinkedHashMap On Sun, May 31, 2020 at 9:12 AM QP Hou <q...@scribd.com> wrote: > I wrote up a quick a go example that uses runtime reflection to work > with object design based off Kamil's java example: > > https://github.com/houqp/airflow-api-clients/blob/master/out/object/go/model_dag_run_test.go > . > > Code wise, it's indeed a little bit more verbose compared to > deserializing/serializing a string. The tradeoff here is it's > verbosity v.s. type safety. > > On Sat, May 30, 2020 at 2:31 AM Jarek Potiuk <jarek.pot...@polidea.com> > wrote: > > > > Ash - QP: also - as Kamil mentioned he already generated multiple clients > > in https://github.com/mik-laj/airflow-api-clients/tree/master/out/object > > so if you have time , maybe you can also take a look in parallel. > > > > On Sat, May 30, 2020 at 11:29 AM Jarek Potiuk <jarek.pot...@polidea.com> > > wrote: > > > > > Kamil - I believe you already have those clients generated - so i will > use > > > them from there. > > > > > > J,. > > > > > > On Sat, May 30, 2020 at 11:26 AM Jarek Potiuk < > jarek.pot...@polidea.com> > > > wrote: > > > > > >> OK. Indeed there seem to be quite some ambiguities and inconsistencies > > >> and the knowledge we are basing our discussion on is a bit fragmented > > >> and "abstract". > > >> > > >> Sorry for being a bit pushy but I think we are not doing enough as a > > >> community to make life our users easier, and we sometimes seem to > > >> proceed without fully understanding of consequences for them - > > >> downplaying the importance of it. And for public API I think this is a > > >> very important topic. > > >> > > >> I think there is an easy way to get a better understanding - simply > > >> use the OpenAPI generator to generate both - clients (in a few > > >> languages) and server stubs (in python) for Airflow and become the > > >> "user" and try to use the client + server and see where we get from > > >> there. This will haunt us for a long time if we make the wrong > > >> decision here. > > >> > > >> For me - this is one of the most important factors on how easy it will > > >> be for someone to use the API once we release it. And being able to > > >> use generated clients in several languages is pretty much > > >> non-negotiable requirement for the API. > > >> > > >> I will spend some time over the weekend trying it out and see whether > > >> the problems that I pointed out are really present in our specs and if > > >> they are - whether can be solved quickly - and if there are problems > > >> and they need some workarounds or customizations - for me it's super > > >> important that we are aware of those problems and we let the users of > > >> our API know how to solve them > > >> > > >> I will be posting some results while I do so - I count on your help QP > > >> and Ash if I see any non-obvious obstacles. > > >> > > >> J. > > >> > > > > > > > > > -- > > > > > > Jarek Potiuk > > > Polidea <https://www.polidea.com/> | Principal Software Engineer > > > > > > M: +48 660 796 129 <+48660796129> > > > [image: Polidea] <https://www.polidea.com/> > > > > > > > > > > -- > > > > Jarek Potiuk > > Polidea <https://www.polidea.com/> | Principal Software Engineer > > > > M: +48 660 796 129 <+48660796129> > > [image: Polidea] <https://www.polidea.com/> > -- Jarek Potiuk Polidea <https://www.polidea.com/> | Principal Software Engineer M: +48 660 796 129 <+48660796129> [image: Polidea] <https://www.polidea.com/>