首页 > 解决方案 > Graphql 工具:将实体类型映射到 graphql 类型

问题描述

我在我的 spring 应用程序中使用了 graphql java 工具。我有一个这样的实体:

@Entity
data class Image(
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        @Column(nullable = false)
        val id: Long = 0
) {
    @Lob
    @Column(nullable = false)
    var image: Blob? = null
}

在 GraphQL 模式中,我希望有不同的类型:

type Image {
    id: ID!
    image: String!
}   

当然,由于模式解析异常,启动它不会起作用。所以我认为必须有可能在模式解析之间放置一些东西来实现从Blob到的映射String

这在某种程度上可能吗?

@Bean
fun schemaParserDictionary(): SchemaParserDictionary {
    return SchemaParserDictionary()
}

编辑

抱歉,它不会给出模式解析异常。它只会将字节放入字符串中。但是我不能使用那个字符串来创建图像。

澄清

对不起,我想我的问题不够清楚。我不需要知道如何将 blob 转换为字符串。有非常简单的解决方案。例如,我可以使用一个简单的 API 函数将字节码转换为 base64:

val base64 = Base64.getEncoder().encodeToString(byteCode)

我想问的是如何“告诉”graphql 模式解析器为特定字段使用“自定义”转换。因此,当我的实体对象具有image数据类型blob为 graphql 的字段时,它会自动将其转换为string. 但字符串不包含我需要的内容。所以我想为那个特定的字段使用自定义解析/映射/转换/任何东西。当然,我也可以通过引入另一个我不存储在数据库中的字段来轻松解决这个问题:

@Entity
data class Image(
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        @Column(nullable = false)
        val id: Long = 0
) {
    @Lob
    @Column(nullable = false)
    var image: Blob? = null

    @Transient
    var base64: String = ""
}

但我可以通过 graphql api 进行查询:

type Image {
    id: ID!
    image: String!
    base64: String!
}

type Images {
    images: [Image!]!
    totalCount: Int!
}

type Query {
    getImages: Images!
}

并将其设置在我的控制器中:

private fun getImages(): Images {
    var images: List<Image> = repository.findTop1000()

    images.forEach {
        it.base64 = Base64.getEncoder().encodeToString(it.image)

        queue.offer(it)
    }
}

但是如果我可以告诉 graphql 模式解析器这样做会更干净。

标签: springkotlingraphqlgraphql-java

解决方案


Kushal 的回答提供了将 Blob 转换为字符串的片段。要使用此转换,最好使用 DTO。

为此,请将您的 graphql 模式转换为:

type ImageDTO {
    id: ID!
    image: String!
} 

并创建一个 DTO 类 ImageDTO:

public class ImageDTO {
    private Image entity;

    //Constructor
    public ImageDTO(Image image) {
         this.entity=image;
    }

    //Getters
    public Long getId() {
        return entity.getId();
    }

    public String getImage() {
        //convert the entity image and return it as String
        return Base64.getEncoder().encodeToString(entity.getImage());
    }
}

将 DTO 与实体分离可以让您更好地控制传输的数据。


推荐阅读