Skip to content

Allow serialization/deserialization of enums using kebab-case. #5092

Closed
@garretwilson

Description

@garretwilson

Is your feature request related to a problem? Please describe.

The Java world (and many other languages) uses mostly camelCase identifiers, except for constants (in particular enums), which are identified with UPPER_SNAKE_CASE. However the modern web world uses (lowercase) kebab-case for identifiers. You can see this in:

  • URI path segments
  • URI path slugs
  • CSS classes
  • HTML values
  • etc.

Modern web frameworks such as Angular and Vue translate between the two worlds (in this case, the worlds of JavaScript/TypeScript and the web) transparently. Similarly I'm sure you're aware that JavaScript-based DOM methods use camelCase identifiers when accessing kebab-case data, both for standard attributes and actual custom data attributes.

I'm creating an entire framework that needs to convert Java enum UPPER_SNAKE_CASE to kebab-case and back transparently when serializing/deserializing.

Issue #3053 got us half the way there, but really that feature request was specific to the requestor's use case. I'm not saying that functionality is never useful. I'm saying that the usage of kebab-case (this request) in the modern web world is overwhelmingly more needed than lower_snake_case (which is effectively what #3053 produces).

Describe the solution you'd like

We need a feature to tell Jackson to serialize/deserialize an enum value such as FOO_BAR as foo-bar. Perhaps EnumFeature.WRITE_ENUMS_TO_KEBAB_CASE would work. (I assume/hope that the implementation of #3053 handles deserialization as well? I haven't tried it.)

Usage example

No response

Additional context

As I workaround, I've thrown together part of a proof of concept to override serialization. I could use some help on this so I can complete it and use it in the interim:

.addModule(new SimpleModule() //
    .addSerializer(Enum.class, new JsonSerializer<Enum>() {
      @Override
      public void serialize(Enum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(value.name().toLowerCase().replace('_', '-'));
      }
    })
    .addKeySerializer(Enum.class, new JsonSerializer<Enum>() {
      @Override
      public void serialize(Enum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeFieldName(value.name().toLowerCase().replace('_', '-'));
      }
    })

This works for serialization, although it's a shame to use raw Enum. I couldn't immediately figure out a way to prevent the warning, even using Enum<?> and the like.

However I don't see how to create a deserializer that will override the behavior for all enums. The com.fasterxml.jackson.databind.deser.std.EnumDeserializer class is huge! Is there some way to override that and do a pre-transformation on the token or something? Or is there a simpler way to add a new custom enum serializer with this functionality?

How best to add a quick-and-dirty workaround until (and if) Jackson adds this feature natively? Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    to-evaluateIssue that has been received but not yet evaluated

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions