Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pagination is not supported with decode fein in Java Spring boot #268

Open
SoheibOuad opened this issue Jun 28, 2024 · 2 comments
Open

Pagination is not supported with decode fein in Java Spring boot #268

SoheibOuad opened this issue Jun 28, 2024 · 2 comments

Comments

@SoheibOuad
Copy link

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);
}

}`

@jasminb
Copy link
Owner

jasminb commented Jul 9, 2024

@SoheibOuad thank you for reporting the issue, I will try to investigate next week. Cheers!

@jasminb
Copy link
Owner

jasminb commented Jul 31, 2024

@SoheibOuad there must be something off in how you are deciding when to use readDocument and when to use readDocumentCollection as it works for in the following unit test:

	@Test
	public void testReportedIssue() throws IOException {
		converter.registerType(CollectionDeserIssue.class);
		String data = "{\"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\"}}}";
		JSONAPIDocument<List<CollectionDeserIssue>> deser = converter.readDocumentCollection(data.getBytes(StandardCharsets.UTF_8), CollectionDeserIssue.class);
		System.out.println(deser.get().get(0).getTitle());
	}


	@Type("node--demande_de_support")
	static class CollectionDeserIssue {
		@Id
		private String id;
		@JsonProperty("title")
		String title;
		@JsonProperty("field_statut_de_la_demande")
		String status;
		@JsonProperty("changed")
		String modificationDate;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants