google / google/gson

Question re: type adapters and field annotations

Open
#1,818 1 comment 2 reactions 0 assignees View on GitHub
enhancement
Dominant language
Java
Stars
24.2k
Forks
4.5k
Avg merge
6d 4h
Merged PRs (30d)
12

Description

Hi, I have a need to define a type adapter (or type adapter factory, etc.) that will support two different flavors of `java.util.Date` serialization/deserialization. At a high level, I'd like to be able to:
1. implement a type adapter factory that is registered for the `java.util.Date` class
2. define a custom annotation that can be placed on a class field of type `java.util.Date` (or `List`, `Map`, etc.) and will be used to specify the precise "flavor" of date/time values that should be read/written from/to JSON for that field. The two flavors would be "date" and "date-time" as defined by the OpenAPI Specification.

I have some experience in implementing type adapter factories, including one that uses reflection on the class that it handles in order to guide the serialization and deserialization steps. But, I can't seem to find a way to accomplish the above.
Specifically, I'd like to be able to define fields within a java class, something like this:
```
public class MyModel
@my.pkg.annotations.OpenAPIDateFormat("date") // or @my.pkg.annotations.OpenAPIDate
private java.util.Date date_field;

@my.pkg.annotations.OpenAPIDateFormat("date-time") // or @my.pkg.annotations.OpenAPIDateTime
private java.util.Date date_time_field;
}
```

I would like to avoid having to implement my own versions of existing Gson-provided type adapters and instead focus on a type adapter that is registered specifically for `java.util.Date` and also is able to access the field annotations as in the example above in order to dynamically determine how values of the field should be serialized/deserialized - either as a date (e.g. `2020-01-01`) or a date-time (e.g. `2020-01-01T12:00:00.000Z`).

Is it possible for a type adapter associated with a specific class (type) to access the metadata (e.g. annotations) of fields defined with that type?

One approach that I've started to implement is like this:
```
public class MyModel
@JsonAdapter(my.pkg,adapters.OpenAPIDateSerializer)
private java.util.Date date_field;

@JsonAdapter(my.pkg,adapters.OpenAPIDateTimeSerializer)
private java.util.Date date_time_field;
}
```
I use the `@JsonAdapter` annotation to specify the specific flavor of serialization/deserialization that should be performed on a field level. This works fine for scalars, but it looks like I'd need to define a separate pair of adapters for each unique scenario (`List,` `List>`, `Map`, `Map>`, etc.). I'd like to avoid that if possible.

In the future, we could potentially change our model class generation approach[1] where we define class fields using different classes for date and date-time values (e.g. `java.time.LocalDate` for date and `java.time.LocalDateTime` or `java.time.ZonedDateTime` for date-time values). In that scenario, we could simply register the appropriate type adapter for each of the classes and that would settle it, but for at least the near term, we need to continue to use class fields of type `java.util.Date` to represent both date and date-time values.

Any help would be appreciated!

[1] - This problem is within the context of some tooling that supports the generation of client-side SDK code from an OpenAPI specification. In this environment, I control how the model classes are generated and I also control the underlying enabling layer that might contain Gson type adapters needed to support the particular chosen generation approach. For the short term, we will need to continue using `java.util.Date` to represent date and date-time values in the generated model classes, because any change to that type mapping would present breaking changes to SDK users. In the future, we can explore a new generation model where we could potentially use different classes for "date" and "date-time" values.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.