FasterXML / FasterXML/jackson-future-ideas

Group-based approach to context-based serialization

Aperta
#58 1 commento 1 reazione 0 assegnatari Vedi su GitHub
Lingua principale
Nessun dato sulla lingua
Stelle
21
Fork
3
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

**Is your feature request related to a problem? Please describe.**
Every so often, I have a desire to de/serialize the same object differently in different contexts. This can be accomplished today by writing different mixins for each context. Alternatively, if it's just a difference of field inclusion, the [`@JsonView`](http://fasterxml.github.io/jackson-annotations/javadoc/2.12/com/fasterxml/jackson/annotation/JsonView.html) annotation can be used.

On thing that feels clunky with the mixin approach is that the contextual configuration differences are declared in two different code locations. To figure out how any given field might be serialized, both locations need to be viewed and compared.

Mixins also have to be declared at `ObjectMapper` creation time, whereas views can be varied per request:

```java
objectMapper.writerWithView(MyView.class).writeValueAsString(myValue);
objectMapper.readerWithView(MyView.class).readValue(json, MyType.class);

objectMapper.copy().addMixIn(MyType.class, MyMixin.class).writeValueAsString(myValue);
objectMapper.copy().addMixIn(MyType.class, MyMixin.class).readValue(json, MyType.class);
```

Mixins are difficult to use per-request in the [Spring Web](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html) framework since it generally assumes a single `ObjectMapper` and it requires quite a bit of non-obvious cumbersome configuration to support different `ObjectMapper`s for different endpoints. On the other hand, [JSON views](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-jsonview) have first class support:

```java
@RestController
public class UserController {
@GetMapping("/user")
@JsonView(User.WithoutPasswordView.class)
public User getUser() {
return new User("eric", "7!jd#h23");
}
}
```

In summary, while powerful, mixins have a few strikes against them in the usability department. JSON views, on the other hand, only work for property exclusion, and cannot be used for other kinds of serialization differences.

**Describe the solution you'd like**
It would seem like a group-based mechanism like `JsonView` that would work for any Jackson configuration annotation would be handy, and would fit well with Jackson, as an alternative to using mixins.

Other annotation-based libraries in the Java ecosystem do similar. The main one that comes to mind is [Jakarta Bean Validation](https://beanvalidation.org) with its [validation groups](https://beanvalidation.org/2.0/spec/#validationapi-validatorapi-groups):

> ```java
> /** Validates a minimal set of constraints */
> public interface Minimal {}
>
> public class Address {
>
> @NonEmpty(groups = Minimal.class)
> @Size(max=50)
> private String street1;
>
> @NonEmpty
> private String city;
>
> @NonEmpty(groups = {Minimal.class, Default.class})
> private String zipCode;
>
> [...]
> }
> ```

**Usage example**
One option would be to add a `groups` (or `group`) element to literally every annotation type like Jakarta Bean Validation does, in which case it would look very similar to the above Jakarta Bean Validation example:

```java
public class Address {
@JsonFormat(pattern = "MM/dd/yyyy", groups = ExternalApi1.class)
@JsonFormat(shape = NUMBER, groups = ExternalApi2.class)
@JsonFormat(pattern = "yyyy-MM-dd") // The default if no group
private LocalDate myField;
}
```

If you didn't want to add `groups` to every single Jackson annotation, an alternate approach might be to put the annotations inside a dedicated grouping annotation:

```java
@JsonGroup(group = ExternalApi1.class, annotations = {@JsonFormat(pattern = "MM/dd/yyyy")})
@JsonGroup(group = ExternalApi2.class, annotations = {@JsonFormat(shape = NUMBER)})
@JsonFormat(pattern = "yyyy-MM-dd") // The default if no group
private LocalDate myField;
```

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.