Skip to content

[Feature] Symmetric request/response validation keys and response error.code policy expansion #20

@limehee

Description

@limehee

Problem statement

Request and response validation keys are not fully symmetric in naming and structure, which makes configuration harder to understand and maintain. We should provide the same pattern on both sides for ID rules, duplicate-member handling, and field-contamination rules, and define explicit option policies (default, validation rule, failure behavior).

Proposed solution

  1. Shared version and id-member policies
  • jsonrpc.validation.request.require-json-rpc-version-20

    • Default: true
    • Rule: request jsonrpc must be exactly "2.0"
    • Failure: -32600 INVALID_REQUEST
  • jsonrpc.validation.response.require-json-rpc-version-20

    • Default: true
    • Rule: response jsonrpc must be exactly "2.0"
    • Failure: -32600 INVALID_REQUEST (response-side validation exception)
  • jsonrpc.validation.request.require-id-member

    • Default: false
    • Rule: optionally require id member in request
    • RFC note: default remains false because JSON-RPC 2.0 allows Request objects without id (Notification)
    • Failure (when enabled): -32600 INVALID_REQUEST
  • jsonrpc.validation.response.require-id-member

    • Default: true
    • Rule: require id member in response
    • Failure: -32600 INVALID_REQUEST
  1. Shared id-type policies
  • jsonrpc.validation.request.allow-string-id

  • jsonrpc.validation.response.allow-string-id

    • Default: true
    • Rule: allow string id
    • Failure on disallowed value: -32600
  • jsonrpc.validation.request.allow-numeric-id

  • jsonrpc.validation.response.allow-numeric-id

    • Default: true
    • Rule: allow numeric id
    • Failure on disallowed value: -32600
  • jsonrpc.validation.request.allow-null-id

  • jsonrpc.validation.response.allow-null-id

    • Default: true
    • Rule: allow id: null
    • Failure on disallowed value: -32600
  • jsonrpc.validation.request.allow-fractional-id

  • jsonrpc.validation.response.allow-fractional-id

    • Default: true
    • Rule: allow fractional numeric id
    • Failure on disallowed value: -32600
  1. Shared duplicate-member policies
  • jsonrpc.validation.request.reject-duplicate-members

    • Default: false
    • Rule: reject duplicate object members in request payload
    • Failure: use one fixed code consistently (-32700 PARSE_ERROR or -32600 INVALID_REQUEST)
  • jsonrpc.validation.response.reject-duplicate-members

    • Default: false
    • Rule: reject duplicate object members in response payload
    • Failure: response-side parse/validation exception (mapped consistently)
  1. Symmetric field-contamination policies
  • jsonrpc.validation.request.reject-response-fields

    • Default: false
    • Rule: reject request containing result or error
    • Failure: -32600 INVALID_REQUEST
  • jsonrpc.validation.response.reject-request-fields

    • Default: false
    • Rule: reject response containing method or params
    • Failure: -32600 INVALID_REQUEST
  1. Response error.code policy group
  • jsonrpc.validation.response.error-code.policy

    • Default: ANY_INTEGER
    • Policies:
      • ANY_INTEGER: pass when integer
      • STANDARD_ONLY: allow JSON-RPC standard error codes only
      • STANDARD_OR_SERVER_ERROR_RANGE: allow standard + server error range
      • CUSTOM_RANGE: allow only user-defined range
  • jsonrpc.validation.response.error-code.range.min

  • jsonrpc.validation.response.error-code.range.max

    • Default: none
    • Rule: required when policy=CUSTOM_RANGE
    • Constraint: min <= max
    • Failure on invalid config: fail fast at startup
  1. Keep existing request params policy
  • jsonrpc.validation.request.params-type-violation-code-policy
    • Default: INVALID_PARAMS
    • Rule: map params shape/type violations to INVALID_PARAMS or INVALID_REQUEST

Implementation scope:

  • Core parser/validator/options updates
  • Spring properties and auto-configuration wiring
  • configuration metadata and IDE hints updates
  • unit/integration/e2e tests (success/failure/branch/exception)
  • README/docs examples synchronization

Alternatives considered

  • Expanding request-side only
  • Adding partial keys without structural symmetry

Rejected because these approaches keep configuration inconsistent and increase long-term maintenance cost.

JSON-RPC behavior impact

No default protocol breaking behavior is intended.
Behavior changes occur only when stricter options are enabled.

Additional context

Acceptance criteria:

  • Symmetric request/response key patterns where applicable
  • Option policy docs include defaults, validation rules, and failure behavior
  • ./gradlew check passes
  • docs, metadata, and implementation are fully aligned

Migration notes

This change requires migration for existing response validation keys.

Required key renames:

  • jsonrpc.validation.response.require-response-id-member -> jsonrpc.validation.response.require-id-member
  • jsonrpc.validation.response.allow-string-response-id -> jsonrpc.validation.response.allow-string-id
  • jsonrpc.validation.response.allow-numeric-response-id -> jsonrpc.validation.response.allow-numeric-id
  • jsonrpc.validation.response.allow-null-response-id -> jsonrpc.validation.response.allow-null-id
  • jsonrpc.validation.response.allow-fractional-response-id -> jsonrpc.validation.response.allow-fractional-id

Semantic inversion:

  • Old: jsonrpc.validation.response.allow-request-fields-in-response
  • New: jsonrpc.validation.response.reject-request-fields
  • Mapping rule: reject-request-fields = !allow-request-fields-in-response

No default-value flip is required for jsonrpc.validation.request.require-id-member.

  • It remains false by design because JSON-RPC Notifications are valid requests without id.

New additive keys (no migration required if previously unused):

  • jsonrpc.validation.request.allow-string-id
  • jsonrpc.validation.request.allow-numeric-id
  • jsonrpc.validation.request.allow-null-id
  • jsonrpc.validation.request.allow-fractional-id
  • jsonrpc.validation.request.reject-response-fields
  • jsonrpc.validation.request.reject-duplicate-members
  • jsonrpc.validation.response.reject-duplicate-members
  • jsonrpc.validation.response.error-code.policy
  • jsonrpc.validation.response.error-code.range.min
  • jsonrpc.validation.response.error-code.range.max

Documentation requirements:

  • Add old->new key mapping table in docs/configuration-reference.md
  • Add before/after YAML examples in README and Spring Boot guide
  • Reflect canonical keys in configuration metadata/IDE hints
  • Include migration section in release notes

Metadata

Metadata

Assignees

Labels

type: featureNew feature specification and implementation.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions