-
Notifications
You must be signed in to change notification settings - Fork 85
Description
I do this to retrieve the links information that is in the root of the json-api response to manage pagination
I get this error when I retrieve the result from jsonapi: feign.codec.DecodeException: Primary data must be either a single resource object, a single resource identifier object, or null
I have this response model from jsonapi.
{ "data": [ { "type": "node--demande_de_support", "id": "1", "attributes": { "title": "value1", "field_statut_de_la_demande": "value2", "changed": "value3" } } ], "links": { "next": { "href": "https://url/jsonapi/node/demande_de_support? include=field_objet_de_la_demande&page%5Boffset%5D=50&page%5Blimit%5D=50" }, "self": { "href": "https://url/jsonapi/node/demande_de_support?include=field_objet_de_la_demande" } } }
This is the model DTO that will be contain the converted
`@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class DrupalSavRequestResponseDTO {
private List<DrupalSavRequestDTO> data;
@Links
private com.github.jasminb.jsonapi.Links links;
}`
and DrupalSavRequestDTO is :
`@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
@type("node--demande_de_support")
public class DrupalSavRequestDTO extends JsonApiBaseModel {
@JsonProperty("title")
String title;
@JsonProperty("field_statut_de_la_demande")
String status;
@JsonProperty("changed")
String modificationDate;
}`
I'm using jsonapi-converter in my project java spring boot to decode and encode using this configuration :
`import feign.RequestInterceptor ;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import com.github.jasminb.jsonapi.ResourceConverter;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.codec.ErrorDecoder;
@slf4j
public class JsonApiControllerConfiguration {
public JsonApiControllerConfiguration() {
}
@Bean
public Encoder feignEncoder() {
ResourceConverter resourceConverter = new ResourceConverter(Test.class);
return new JsonApiEncoder(resourceConverter);
}
@Bean
public Decoder feignDecoder() {
ResourceConverter resourceConverter = new ResourceConverter(Test.class);
return new JsonApiDecoder(resourceConverter);
}
@Bean
public ErrorDecoder errorDecoder() {
return new CustomErrorDecoder();
}
}`
And i have custom JsonApiDecoder :
`import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Collection;
import com.github.jasminb.jsonapi.JSONAPIDocument;
import com.github.jasminb.jsonapi.ResourceConverter;
import feign.Response;
import feign.codec.Decoder;
import java.lang.reflect.ParameterizedType;
import lombok.extern.slf4j.Slf4j;
@slf4j
public class JsonApiDecoder implements Decoder {
private final ResourceConverter resourceConverter;
public JsonApiDecoder(ResourceConverter resourceConverter) {
this.resourceConverter = resourceConverter;
}
@Override
public Object decode(Response response, Type type) throws IOException {
if (response.body() == null) {
return null;
}
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type actualType = parameterizedType.getActualTypeArguments()[0];
if (actualType instanceof Class<?>) {
Class<?> clazz = (Class<?>) actualType;
JSONAPIDocument<?> document;
if (Collection.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())) {
document = resourceConverter.readDocumentCollection(response.body().asInputStream(),
clazz);
} else {
document = resourceConverter.readDocument(response.body().asInputStream(),
clazz);
}
return document.get();
}
}
if (type instanceof Class<?>) {
Class<?> clazz = (Class<?>) type;
JSONAPIDocument<?> document = resourceConverter.readDocument(response.body().asInputStream(), clazz);
return document.get();
}
throw new IOException("Type not supported: " + type);
}
}`