FasterXML / FasterXML/jackson-dataformats-binary

Support @JsonSubTypes in schema generation and serialization

Aberta
#11 6 comentários 0 reações 0 responsáveis Ver no GitHub
avro
Linguagem predominante
Java
Estrelas
347
Forks
156
Merge médio
3d 3h
PRs com merge (30d)
22

Descrição

(moved from https://github.com/FasterXML/jackson-dataformat-avro/issues/28 authored by @osi)

I'd like to get the JsonSubTypes annotation working for schema generation and serialization.

For schema generation, I think it should be a union of all the possible sub-types.

For serialization, if the configuration is such that the type name would be included as a property, ignore that, since it will be included as the name of the record type.

I have written some failing tests, but it is unclear to me how to proceed, since the TypeIdResolver doesn't provided a way to interrogate all possible types.

``` java
package com.fasterxml.jackson.dataformat.avro;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.apache.avro.Schema;
import org.junit.Test;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class JsonTypeInfoTest {

@Test
public void testGenerateSchemaForSubTypes() throws Exception {
AvroMapper mapper = new AvroMapper();
AvroSchema schema = mapper.schemaFor(Thing.class);

Schema stringOrNull = Schema.createUnion(Arrays.asList(Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.STRING)));
Schema thingOne = Schema.createRecord(
ThingOne.class.getSimpleName(),
"Schema for " + ThingOne.class.getName(),
ThingOne.class.getPackage().getName(),
false);
thingOne.setFields(Arrays.asList(
new Schema.Field("favoriteColor", stringOrNull, null, null),
new Schema.Field("name", stringOrNull, null, null)
));

Schema thingTwo = Schema.createRecord(
ThingTwo.class.getSimpleName(),
"Schema for " + ThingTwo.class.getName(),
ThingTwo.class.getPackage().getName(),
false);
thingTwo.setFields(Arrays.asList(
new Schema.Field("favoriteFood", stringOrNull, null, null),
new Schema.Field("name", stringOrNull, null, null)
));

Schema expected = Schema.createUnion(Arrays.asList(thingOne, thingTwo));
assertEquals(expected, schema.getAvroSchema());
}

@Test
public void testSerializeSubType() throws Exception {
AvroMapper mapper = new AvroMapper();
AvroSchema schema = mapper.schemaFor(Thing.class);

assertNotNull(mapper.writer(schema).writeValueAsBytes(new ThingOne("hello", "blue")));
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "@type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ThingOne.class, name = "one"),
@JsonSubTypes.Type(value = ThingTwo.class, name = "two")
})
public interface Thing {
@JsonProperty
String name();
}

public static class ThingOne implements Thing {
public final String favoriteColor;
private final String name;

public ThingOne(String name, String favoriteColor) {
this.name = name;
this.favoriteColor = favoriteColor;
}

@Override
public String name() {
return name;
}
}

public static class ThingTwo implements Thing {
public final String favoriteFood;
private final String name;

public ThingTwo(String name, String favoriteFood) {
this.name = name;
this.favoriteFood = favoriteFood;
}

@Override
public String name() {
return name;
}
}
}
```

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.