GraphQL, how to return type of byte[]

Chris Turner :

I have thumbnails saved in my database as a byte array. I can't seem to workout how to return these to the frontend clients via GraphQL.

In a standard REST approach I just send a POJO back with the bytes and I can easily render that out.

However trying to return a byte[] is throwing

Unable to match type definition (ListType{type=NonNullType{type=TypeName{name='Byte'}}}) with java type (class java.lang.Byte): Java class is not a List or generic type information was lost: class java.lang.Byte

The error is descriptive and tells me what's wrong, but I don't know how to solve that.

My thumbnail.graphqls looks like:

type Thumbnail {
    id: ID!
    resource: [Byte!]
}

And the thumbnail POJO

public class Thumbnail extends BaseEntity {
    byte[] resource;
}

I'm using graphql-spring-boot-starter on the Java side to handle things, and I think it supports Byte out the box, so where have I gone wrong?

Very fresh to GraphQL so this could just be an obvious mistake.

Cheers,

Alkis Mavridis :

You have to serialize it to one of the standard types. If you want your byte array to look like a string such as "F3269AB2", or like an array of integers such as [1,2,3,4,5] its totally up to you.

You can achieve the serialization by writing a resolver for your entity, like that:

public class ThumbnailResolver extends GraphQLResolver<Thumbnail> {
        public String resource(Thumbnail th) { ... }
        //or List<Integer> resource(Thumbnail th) { ... }
        //or whatever
    }

The resolver have always priority over your entity. This means that if a resolver method with the correct name, parameters and return type is found in the resolver class, this will be called instead of the entity method. This way we can "override" entity methods, in order to return an other result, even a different type than the actual entity field. By using resolvers, we could also have access to application scoped services etc that an entity typically does not have.

After writing your resolver, don't forget to update your schema file to:

resource: String
#or resource:[Int]
#or whatever

Your schema should refere to the resolver type since this is what graphQL recieves. The actual entity type will become then irrelevant to graphQL.

As a plan B, you could implement a new Scalar. This would be like inventing a new basic type. This is also not that hard. You can see the already existing scalar types here and do something similar.

You can then name your new type ByteArray or something like that, declare it in your schema:

scalar ByteArray

and then use it.

I would go for the first solution though since it is easier and faster to implement.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=109867&siteId=1