microsoft / microsoft/multiclouddb-sdk-for-java

Decouple document serialization from the portable API before preview

Open
#116 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
7
Forks
7
Avg merge
1d 22h
Merged PRs (30d)
1

Description

Context

The portable API currently exposes Jackson-specific types and dependencies:

  • DocumentResult.document() returns Jackson ObjectNode.
  • ChangeEvent.data() returns Jackson JsonNode.
  • multiclouddb-api declares
    requires transitive com.fasterxml.jackson.databind.
  • Write inputs accept Map<String, Object> with behavior determined by an
    SDK-owned Jackson configuration.

microsoft/multiclouddb-sdk-for-java#105 additionally introduces a validation
pipeline that snapshots and traverses the input, serializes it with an internal
ObjectMapper, reparses it as a JsonNode, validates it again, converts it back
to a map, and then performs another provider-specific conversion. Caller
Jackson modules and serializer configuration are intentionally ignored.

Review discussion concluded that this creates both a public API compatibility
risk and avoidable serialization/allocation overhead. The serializer
architecture should be settled before further preview or GA release.

Goals

  • Remove serialization-implementation types from the portable public contract.
  • Allow customers to choose and independently configure their object serializer.
  • Keep Jackson available as a supported default adapter.
  • Keep portable validation and provider-native mapping under SDK control.
  • Avoid serialize/reparse/convert cycles before provider delegation.
  • Give Cosmos DB, DynamoDB, and Spanner one explicit value model for portable
    null, number, object, array, and binary behavior.

Proposed architectural direction

Separate two boundaries:

  1. Customer object mapping

    • A customer-extensible DocumentCodec/CodecProvider converts POJOs and
      generic Java types to and from the portable document model.
    • Codec instances have an explicit thread-safety and lifecycle contract.
    • Jackson support lives in a separate adapter artifact that can accept a
      customer-configured ObjectMapper.
  2. Portable document and provider mapping

    • multiclouddb-api owns an immutable Document/DocumentValue model with
      no Jackson dependency.
    • Provider modules convert this neutral model directly to Cosmos payloads,
      DynamoDB AttributeValue, and Spanner values.
    • Codec output remains subject to portable validation and provider
      capability checks.

Potential module layout:

  • multiclouddb-api: neutral document, patch, codec, error, and limit contracts
  • multiclouddb-core: standard conversion and validation without Jackson
  • multiclouddb-serializer-jackson: optional/default Jackson adapter
  • optional future Gson or JSON-B adapters
  • provider modules: neutral-document to provider-native conversion

azure-json-style token readers/writers may be evaluated as an internal
streaming implementation, but should not become public API until their
ownership, numeric, duplicate-key, limit, and error contracts are stable.

Required contract decisions

  • Missing field versus explicit null
  • Exact numeric representation and provider round-trip guarantees
  • Duplicate object-key handling
  • Binary representation and whether binary is part of the portable profile
  • Supported Java types for Map<String, Object> convenience overloads
  • Codec selection and precedence
  • Client-wide versus per-operation codec configuration
  • Thread safety and lifecycle
  • Depth, field-name, token-count, structural, and serialized-size limits
  • Stable path-aware errors without logging document contents
  • Read, query, change-feed, and partial-update result types

Acceptance criteria

  • No Jackson type appears in the neutral API signatures.
  • multiclouddb-api no longer requires Jackson transitively.
  • DocumentResult, QueryPage, and ChangeEvent use the same neutral document
    representation.
  • Arbitrary POJOs are accepted only through an explicit codec; unknown values
    are not silently stringified or passed through a hidden mapper.
  • The Jackson adapter supports a safe default and a caller-configured
    ObjectMapper.
  • Cosmos DB, DynamoDB, and Spanner map the neutral representation directly to
    native values.
  • Validation does not require the current
    snapshot → serialize → parse → convert → provider-convert cycle.
  • Benchmarks cover representative payload sizes, nesting, POJOs, allocation,
    latency, and limit-boundary behavior.
  • Conformance tests cover null versus absence, numeric fidelity, duplicate
    keys, binary policy, codec failures, and provider round trips.
  • Migration guidance is provided for existing ObjectNode/JsonNode callers.
  • Jackson advisories and supported adapter-version ranges remain part of normal
    dependency maintenance; the abstraction must not claim to eliminate CVE
    obligations.

Delivery plan

This should be a standalone prerequisite change based on canonical main, not
a branch stacked on microsoft/multiclouddb-sdk-for-java#105:

  1. Agree on an ADR/spec defining the stable public contract.
  2. Implement the neutral model, codec boundary, Jackson adapter, provider
    mappings, migration utilities, conformance, and benchmarks.
  3. Rebase microsoft/multiclouddb-sdk-for-java#105 onto the merged foundation.
  4. Reimplement partial-update validation and provider mapping using the neutral
    model.
  5. Do not merge or release #105 with the current serializer contract first.

Non-goals

  • Removing every internal use of Jackson
  • Claiming that a serializer abstraction eliminates dependency vulnerabilities
  • Allowing arbitrary serializer output to bypass portable validation
  • Exposing provider-native value types through the portable API

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by drafting the ADR/spec for the neutral document model, codec boundary, and required contract decisions. Inspect DocumentResult, QueryPage, ChangeEvent, and the multiclouddb-api dependency declaration, then trace provider mappings and validation. Done means the acceptance criteria are met, including conformance tests, benchmarks, and migration guidance.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend-api-design, databases
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.