Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command deserialization #1972

Open
pintomau opened this issue Aug 27, 2019 · 1 comment
Open

Command deserialization #1972

pintomau opened this issue Aug 27, 2019 · 1 comment

Comments

@pintomau
Copy link

Hi.

On our services, we're trying to keep API compatibility with Commercetools while enriching it where we need to.

For example, if some client application sends us a cart creation request json, we can deserialize it using the CartDraft model and enrich the request specific to our platform:

  public Cart save(final CartDraft cartDraft) {

    final CustomFieldsDraft originalCustom = cartDraft.getCustom();

    final CustomFieldsDraft enrichedCustom =
        CustomFieldsDraftBuilder
            // force CE custom type
            .ofTypeKey(CE_CUSTOM_TYPE_KEY)
            // carry over any custom fields, if they exist
            .fields(
                originalCustom == null || originalCustom.getFields() == null
                    ? new HashMap<>()
                    : new HashMap<>(originalCustom.getFields()))
            // add sourceId field
            .addObject(CART_SOURCE_ID_FIELD_NAME, ctx.getSourceId())
            .build();

    final CartDraftDsl enrichedCart = CartDraftDsl.of(cartDraft).withCustom(enrichedCustom);
    return executor.executeBlocking(CartCreateCommand.of(enrichedCart));
  }

Now we wanted to go further here and also enrich/control Update Commands, for example limit what actions a client can execute, add commands on top of what the client sends us...

We've also considered using HTTP API extensions for this, but since it lacks context (which actions were executed and what the cart looked like before it was changed), we can't do the full scope of interactions/validations we wanted to. Also, it saves another roundtrip.

What we want to achieve would look something like this:

  @PostMapping("{cartId}")
  public ResponseEntity<Cart> updateCart(
      @PathVariable final UUID cartId, @RequestBody final CartUpdateCommand updateCommand) {

    // intercept and manipulate the update command

    // forward the updated command to Commercetools

    // be happy :)
    return null;
  }

We tried shadowing CartUpdateCommand to add @JsonDeserialize(as = CartUpdateCommandImpl.class), but noticed that CartUpdateCommand expects a Versioned<Cart> type that isn't available.

We also tried building an object much like UpdateCommandBody<T>, but the UpdateAction<T> lacks any deserialization context to be able to deserialize into its subtypes.

Wondering if you have any suggestion so we could avoid creating all actions ourselves and then translate them into the Commercetools' model, or maybe we've missed some way to do this in the SDK.

Thanks.

@katmatt
Copy link
Contributor

katmatt commented Mar 16, 2020

@CRYBAT I'm sorry that we didn't reply to your request. And you are right that our current JVM SDK isn't prepared to support deserialization. That means that you have to write your own deserialization. And please keep in mind that our write models (*Draft classes) and our read models are intentionally designed and aren't always compatible with each other.

I hope you already found your own solution and would like to hear about it 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants