0

We use crnk framework for json-api implementation. There is a response body for GET/request body for PATCH:

{
    "data": {
        "id": "1",
        "type": "v1/indicator-data",
        "attributes": {
            "indicatorValues": [
                {
                    "time": "2018-03-25T00:00:00Z",
                    "indicator1": 50
                },
                {
                    "time": "2018-03-26T00:00:00Z",
                    "indicator1": 50
                }  
            ]
        }
    }
}

But depending on some external flag the body and returned indicator may be slightly different:

{
    "data": {
        "id": "2",
        "type": "v1/indicator-data",
        "attributes": {
            "indicatorValues": [
                {
                    "time": "2018-03-25T00:00:00Z",
                    "indicator2": 15
                },
                {
                    "time": "2018-03-26T00:00:00Z",
                    "indicator2": 15
                }  
            ]
        }
    }
}

In order to achieve this I created the following hierarchy:

@JsonApiResource(type = "v1/indicator-data")
public class IndicatorDataDTO {
    @JsonApiId
    private int id;

    private List<IndicatorTimeEntry> indicatorValues;
}

public class IndicatorTimeEntry {
    private ZonedDateTime time;
}

public class Indicator1TimeEntry extends IndicatorTimeEntry {
    private Double indicator1;
}

public class Indicator2TimeEntry extends IndicatorTimeEntry {
    private Double indicator2;
}

In case @JsonInclude was supported, there would be just 1 TimeEntry class with all the indicator fields in it and all unnecessary indicator values would be set to null.

But as it's not, the above approach was tried, where one of the necessary implementations is manually set in the mapper.

So far it works well for GET method, while during PATCH the body is automatically mapped by crnk to IndicatorTimeEntry and indicator1/2 values are lost. Is it possible to extend/perform manual mapping from json to necessary dto child calss? Or maybe another approach could be tried?

funny-shmunny
  • 87
  • 1
  • 13
  • 1
    you should forget about polymorphism while dealing with json. json does not have any namespace or any class annotation to figure out which subclass it is. Just have one class with all the attributes. Note that it is just a DTO. Your internal model can be very rich but the DTO should be dumb. – gagan singh Jul 02 '18 at 10:16
  • @gagansingh the problem is that given framework doesn't support JsonInclude(Include.NON_NULL) annotation. And having a bunch of null values in the response isn't appropriate in our case. – funny-shmunny Jul 02 '18 at 10:21
  • does the framework support writing your own reader and writers for a class? that could be an approach you can take for these corner cases. – gagan singh Jul 02 '18 at 10:23
  • @gagansingh JSON API specification does support polymorph relationships. – jelhan Jul 02 '18 at 15:54
  • @indicatorValues Is there any reason `indicatorVales` is not modeled as relationship? – jelhan Jul 02 '18 at 15:57
  • @jelhan relationship to what? IndicatorData is in relationship with parental object and it contains these values. – funny-shmunny Jul 02 '18 at 17:07
  • @jelhan there is nothing in the json which can tell whether the elements of indicatorValues array are either Indicator1TimeEntry or Indicator2TimeEntry. How will json deserializer decide? There needs to be some kind of type annotation. Right? – gagan singh Jul 03 '18 at 01:10
  • JSON API spec supports polymorphic *relationships* but `indicatorValues` is not modeled as a relationship at all. It's modeled as an attribute having an array of objects as values. Going into detail how JSON API spec supports polymorphic relationships is to much for a comment. Please ask a separate question or have a deep look into spec at http://jsonapi.org/ – jelhan Jul 03 '18 at 08:22

0 Answers0