Skip to content

Research: Strict schema validation — requiring ALL declared fields in observation results #5

@Sam-Bolling

Description

@Sam-Bolling

Finding

The server strictly validates that ALL fields declared in a datastream's schema are present in every observation result. If any declared field is missing from an observation payload, the server rejects it. This is a research spike to determine whether strict-vs-lenient schema validation is specified by OGC and what the recommended behavior should be.

Review Source: Live integration testing from OSHConnect-Python publishers against both connected-systems-go and OSH SensorHub
Severity: P3-Minor (research spike)
Category: API Design / Validation
Ownership: connected-systems-go


Problem Statement

When a datastream's schema declares a set of observation fields (e.g., timestamp, latitude, longitude, altitude, heading, velocity), the Go server requires that EVERY observation submitted to that datastream includes ALL of those fields. If a publisher omits a field that it considers optional or redundant (e.g., timestamp when resultTime already carries the same information), the server rejects the observation.

Observed behavior:

Datastream schema declares 6 fields including timestamp. Publisher sends:

{
  "resultTime": "2026-04-17T00:00:00Z",
  "result": {
    "latitude": 40.0,
    "longitude": -74.0,
    "altitude": 10500.0,
    "heading": 180.0,
    "velocity": 250.0
  }
}

→ Rejected because timestamp field is missing from result.

Comparative behavior:

Server All fields present Subset of fields Extra fields
OSH SensorHub ✅ Accepted ✅ Accepted (lenient) ✅ Accepted
connected-systems-go ✅ Accepted ❌ Rejected Unknown

Workaround applied: Our publishers now include ALL declared schema fields in every observation, even when some are redundant with top-level fields (e.g., duplicating resultTime as result.timestamp).

Research Questions

This spike should produce analysis, findings, and recommendations that may result in follow-on issues:

  1. What does OGC 23-002 say about observation result validation against the datastream schema? Must all declared fields be present?
  2. Does SWE Common distinguish required vs. optional fields in a DataRecord? Is there a minOccurs="0" concept for individual fields within an observation result?
  3. Should the datastream schema support marking fields as optional? If so, what would the JSON encoding look like?
  4. What's the performance implication of strict validation? Does validating every field of every observation create overhead?
  5. How do other CSAPI implementations handle partial observations? Is SensorHub's leniency intentional or accidental?
  6. Should extra (undeclared) fields be accepted, ignored, or rejected? What about schema evolution — adding a field to a live datastream?
  7. Is there a distinction between "schema defines what CAN appear" vs. "schema defines what MUST appear"?

Expected Deliverables

  • Analysis of OGC spec requirements for observation result validation
  • Review of SWE Common DataRecord optionality mechanisms
  • Comparison table: strict vs. lenient validation across CSAPI servers
  • Recommendation: keep strict, add optional field support, or make configurable
  • If changes are recommended, file follow-on implementation issue(s)

Scope

  • ❌ Do NOT implement changes in this spike — research and recommend only
  • ❌ Do NOT change client-side workarounds — they ensure compatibility with both servers

References

# Document What It Provides
1 OGC 23-002 §9.7 Observation result structure
2 OGC 23-002 §9.3 Datastream schema definition
3 SWE Common 3.0 §7.4 DataRecord component — field optionality
4 OSHConnect-Python opensky_publisher.py Publisher that includes all fields as workaround
5 OSH SensorHub Comparative server with lenient validation

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions