Пользовательский скалярный тип в graphql-spqr

Я graphql-spqr, java.util.Date определяется как Scalar. Можно ли перезаписать сериализацию/десериализацию java.util.Date, чтобы получить другое строковое представление даты?

ScalarStrategy, упомянутая в этом ответе, была удалена в последней версии.

public class Order {

    private String id;
    private Date orderDate; //GraphQLScalarType "Date"

    public Order() {
    }

    public Order(String id, String bookId, Date orderDate) {
        this.id = id;
        this.orderDate = orderDate;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getOrderDate() {
        return orderDate;
    }

    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }
}

Ответ GraphQL:

{
  "data": {
    "createOrder": {
      "id": "74e4816c-f850-4d63-9855-e4601fa125f4",
      "orderDate": "2019-05-26T08:25:01.349Z", // --> 2019-05-26
    }
  }
}

person Patrick    schedule 26.05.2019    source источник
comment
Добавил пример кода в мой ответ. Не идеально, но лучшее, что я могу сделать на своем телефоне.   -  person kaqqao    schedule 08.08.2019


Ответы (1)


ScalarStrategy — неправильный способ добиться того, чего вы хотите. Если вы хотите изменить способ сопоставления типа Java с GraphQL, вы обычно предоставляете новый (или настраиваете существующий) TypeMapper.

Взгляните на существующую скалярную реализацию Date и реализуйте свою собственную аналогичным образом. Затем реализуйте пользовательский TypeMapper, который просто всегда возвращает статический экземпляр этого скаляра из методов toGraphQLType и toGraphQLInputType.

public class CustomTypeMapper implements TypeMapper {

    private static final GraphQLScalarType GraphQLCustomDate = ...;

    @Override
    public GraphQLOutputType toGraphQLType(...) {
        return GraphQLCustomDate;
    }

    @Override
    public GraphQLInputType toGraphQLInputType(...) {
        return GraphQLCustomDate;
    }

    @Override
    public boolean supports(AnnotatedType type) {
        return type.getType() == Date.class; // This mapper only deals with Date
    }
}

Чтобы зарегистрировать его, позвоните по номеру generator.withTypeMappers(new CustomTypeMapper().

Тем не менее, поскольку вы пытаетесь отрезать только временную часть, в идеале вы должны использовать здесь LocalDate. Вы можете заставить SPQR делать это прозрачно, зарегистрировав TypeAdapter (который представляет собой не что иное, как преобразователь + преобразователь), но простой преобразователь, как описано выше, является более эффективным решением в вашем случае. Если вы все же решите пойти по пути адаптера, вы можете унаследовать AbstractTypeAdapter<Date, LocalDate> и реализовать логику преобразования (должна быть тривиальной). Зарегистрируйтесь через generator.withTypeAdapters или зарегистрировав его как маппер и конвертер отдельно.

person kaqqao    schedule 07.08.2019