Documentation
¶
Overview ¶
Package csapi provides Go constants for the OGC API — Connected Systems v1.0 (CS API) vocabulary — specifically the §10 Datastream concept and its surrounding predicates, which SOSA and OMS do not cover.
SOSA models discrete Observations attached to a Sensor; the CS API adds the Datastream concept (§10) — a stream of Observations produced by one System for one ObservableProperty, with temporal bounds and a result-type discriminator. Sister-repo gateways (semconnect, future CS API hosts) that publish or list Datastreams over `POST /datastreams` / `GET /datastreams` need a shared vocabulary primitive so JSON-LD exports resolve and downstream graph consumers can discover Datastreams without grepping for local IRI strings.
Namespace pinning ¶
The Namespace constant pins to the OGC spec-rooted IRI stem for Connected Systems v1.0. The CS API is still a working draft; when the OGC publishes canonical IRIs (which may differ in form), this package gets a one-shot constant swap and existing entities re-tag via the migration playbook. The constant-name surface is the load- bearing API — consumers reference csapi.Datastream etc., not the string form, so the URI change is invisible at the call site.
Coverage ¶
MVP coverage is the load-bearing subset for the CS API §10 → Datastream representation: the Datastream class plus the four predicates needed for the wire shape — ProducedBy, ResultTimeRange, PhenomenonTimeRange, ResultType. The Schema field (SWE Common DataRecord describing observation result structure) is intentionally absent — see [ADR-044] framework-primitives reference §Scope-cut for the rationale (Schema flows as a StorageRef pointer rather than an inline triple).
Typed artifact entities (gh#171) ¶
SensorML source documents, SWE Common result schemas, and SWE Common command schemas are stored as first-class artifact entities — they get their own 6-part EntityID, their own singular StorageRef pointing to the document in NATS ObjectStore, and are related to parent resources (System, Datastream, ControlStream) via vocabulary predicates: HasSource, HasResultSchema, HasCommandSchema. This is "Pattern 2" from the gh#171 triage: the substrate already supports it, no framework primitive change needed, and it cleanly handles the cross-stream reuse case (one schema referenced by N Datastreams without content duplication). See docs/concepts/26-typed-artifact-entities.md.
Standards-at-work, not semweb hell ¶
This package follows the vocabulary family pattern. Constants are exported strings; no OWL inferencing, no SPARQL, no operator- authored RDF. Prefix registration is automatic on import.
Dual-surface predicates (gh#182) ¶
Predicates expose two constants each — a dotted-notation form for internal use in [message.Triple.Predicate] values and an IRI form for JSON-LD / RDF export. Both share a Go identifier base; the IRI form carries the `IRI` suffix:
- csapi.HasSource = "csapi.artifact.source" // dotted, for triples
- csapi.HasSourceIRI = "http://...hasSource" // IRI, for export
- csapi.ProducedBy = "csapi.datastream.producedBy"
- csapi.ProducedByIRI = "http://...producedBy"
Use the dotted form when constructing triples (the framework's NATS wildcard semantics, predicate-index, and rule-engine all rely on the dotted convention). Use the IRI form when serializing for boundary export (JSON-LD `@context`, RDF/Turtle, OGC API responses). The dotted-→-IRI mapping is registered automatically on package import via vocabulary.Register; consumers can also resolve via vocabulary.GetPredicateMetadata.
Class IRIs (Datastream, ControlStream, SensorMLDocument, etc.) have no dotted counterpart — rdf:type values stay IRI-shaped on export and aren't graph predicates themselves.
External references ¶
- Spec (working draft): https://docs.ogc.org/DRAFTS/23-001r0.html
- SOSA (compared/parallel): https://www.w3.org/TR/vocab-ssn/
- OMS bundle (parallel observation vocabulary): [oms]
vocabulary: .. [oms]: ../oms [ADR-044]: ../../docs/adr/044-ogc-connected-systems-framework-split.md
Index ¶
Constants ¶
const ( // Prefix is the CS API short token used when compacting IRIs. Prefix = "csapi" // Namespace is the CS API v1.0 IRI stem. Namespace = "http://www.opengis.net/spec/ogcapi-connectedsystems-1/1.0/" )
CS API namespace identifiers. Pinned to the spec-rooted stem used by OGC API Connected Systems v1.0. The spec is a working draft; when canonical IRIs publish, this constant gets a one-shot swap.
const ( // Datastream — a stream of Observations produced by one System // (sensor or system of systems) for one ObservableProperty, with // declared temporal bounds (PhenomenonTimeRange, // ResultTimeRange) and a result-type discriminator (ResultType). // CS API v1.0 §10. Datastream = Namespace + "Datastream" // ControlStream — a stream of Commands sent to one System // (typically an Actuator-bearing platform) for one // ActuatableProperty. CS API v1.0 Part 2 §14. Draft surface; // IRI swaps to the canonical spec form once published. ControlStream = Namespace + "ControlStream" // Command — an individual instruction issued through a // ControlStream targeting an ActuatableProperty. CS API v1.0 // Part 2 §15. Draft surface; IRI may swap when the spec // publishes. Command = Namespace + "Command" // SystemEvent — a discrete notification about a System // (deployment lifecycle, configuration change, alert). Used // by /systems/{id}/events. CS API v1.0 Part 2 §16. Draft // surface; IRI may swap when the spec publishes. SystemEvent = Namespace + "SystemEvent" // SensorMLDocument — the typed artifact class for a SensorML // XML/JSON document carrying lossless source describing a // System or Procedure. Stored as a first-class artifact entity // (per gh#171 Pattern 2): the artifact carries its own 6-part // EntityID + a singular StorageRef pointing to the document in // ObjectStore. Datastreams and Systems reference it via the // HasSource predicate. Lets parent resources stay graph-shaped // while keeping the heavy document payload addressable via // NATS ObjectStore. SensorMLDocument = Namespace + "SensorMLDocument" // SWESchemaDocument — the typed artifact class for a SWE Common // DataRecord (or higher-arity schema) used by a Datastream or // ControlStream. Stored as a first-class artifact entity with // its own StorageRef. Datastreams reference it via // HasResultSchema; ControlStreams reference it via // HasCommandSchema. The reuse case (one schema across N // streams) is what makes the typed-artifact pattern preferable // to inline embedding on each parent. SWESchemaDocument = Namespace + "SWESchemaDocument" )
CS API class IRIs. Use as the object of an rdf:type triple, or anywhere a Connected-Systems-aware encoder references the type.
const ( // ProducedBy binds a Datastream to the entity ID of the System // (sensor or system of systems) that produces its Observations. // Inverse of a forthcoming `producesDatastream` predicate. // CS API §10. ProducedBy = "csapi.datastream.producedBy" // ResultTimeRange is the ISO 8601 time-interval representation // of the temporal bounds during which the Datastream produced // result values (clock time of the measurements). CS API §10.4. ResultTimeRange = "csapi.datastream.resultTimeRange" // PhenomenonTimeRange is the ISO 8601 time-interval representation // of the temporal bounds of the observed phenomena. May differ // from ResultTimeRange for processed or back-dated observations. // CS API §10.4. PhenomenonTimeRange = "csapi.datastream.phenomenonTimeRange" // ResultType discriminates the structure of the Datastream's // Observations — om:Measurement, om:Category, om:CountObservation, // etc. Consumers branch on this to decode the result payload. ResultType = "csapi.datastream.resultType" // ControlsSystem binds a ControlStream to the entity ID of the // System it targets with Commands. Inverse counterpart to a // forthcoming `hasControlStream`. CS API v1.0 Part 2 §14. ControlsSystem = "csapi.controlstream.controlsSystem" // PartOfControlStream binds a Command to the entity ID of the // ControlStream it was issued through. CS API v1.0 Part 2 §15. PartOfControlStream = "csapi.command.partOfControlStream" // EventForSystem binds a SystemEvent to the entity ID of the // System the event is about. CS API v1.0 Part 2 §16. EventForSystem = "csapi.systemevent.forSystem" // HasSource binds a System or Datastream to the entity ID of // the SensorMLDocument artifact that carries its lossless // source representation. The artifact is a first-class entity // with its own StorageRef pointing to the SensorML XML/JSON in // ObjectStore. Lets parent resources stay graph-shaped // (queryable facts) while the heavy document payload is fetched // on demand via the ObjectStore reference. gh#171. HasSource = "csapi.artifact.source" // HasResultSchema binds a Datastream to the entity ID of the // SWESchemaDocument artifact describing its observation result // structure. Reusable across N Datastreams that share a schema — // the artifact entity holds the canonical schema, the // Datastreams reference it. gh#171. HasResultSchema = "csapi.datastream.resultSchema" // HasCommandSchema binds a ControlStream to the entity ID of // the SWESchemaDocument artifact describing the structure of // commands it accepts. Same reuse model as HasResultSchema. // gh#171. HasCommandSchema = "csapi.controlstream.commandSchema" )
CS API predicate constants — internal dotted-notation form.
Per the framework convention (vocabulary/predicates.go), values flowing through message.Triple.Predicate use three-level dotted notation (`domain.category.property`). IRIs are reserved for export/import boundary serialization. The constants below carry the dotted form; the `*IRI` constants in this file carry the IRI form for JSON-LD / RDF export. Both are exported because callers have legitimate use cases for each:
- Triples: `triple := message.Triple{Predicate: csapi.HasSource, ...}`
- JSON-LD export: `iri := csapi.HasSourceIRI`
The mapping internal → IRI is registered in register.go's init via vocabulary.Register(..., WithIRI(...)) so the framework's export pipeline can resolve either direction.
gh#171 added the artifact-relationship predicates (HasSource, HasResultSchema, HasCommandSchema). gh#182 audited the full set and split each into the dual {dotted, IRI} form.
const ( // ProducedByIRI — CS API IRI for csapi.ProducedBy. ProducedByIRI = Namespace + "producedBy" // ResultTimeRangeIRI — CS API IRI for csapi.ResultTimeRange. ResultTimeRangeIRI = Namespace + "resultTimeRange" // PhenomenonTimeRangeIRI — CS API IRI for csapi.PhenomenonTimeRange. PhenomenonTimeRangeIRI = Namespace + "phenomenonTimeRange" // ResultTypeIRI — CS API IRI for csapi.ResultType. ResultTypeIRI = Namespace + "resultType" // ControlsSystemIRI — CS API IRI for csapi.ControlsSystem. ControlsSystemIRI = Namespace + "controlsSystem" // PartOfControlStreamIRI — CS API IRI for csapi.PartOfControlStream. PartOfControlStreamIRI = Namespace + "partOfControlStream" // EventForSystemIRI — CS API IRI for csapi.EventForSystem. EventForSystemIRI = Namespace + "eventForSystem" // HasSourceIRI — CS API IRI for csapi.HasSource. HasSourceIRI = Namespace + "hasSource" // HasResultSchemaIRI — CS API IRI for csapi.HasResultSchema. HasResultSchemaIRI = Namespace + "hasResultSchema" // HasCommandSchemaIRI — CS API IRI for csapi.HasCommandSchema. HasCommandSchemaIRI = Namespace + "hasCommandSchema" )
CS API predicate IRIs — export/import boundary form.
Use these for JSON-LD export, RDF serialization, and any wire shape that addresses predicates by their canonical OGC IRI. For `message.Triple.Predicate` values inside the framework, use the dotted constants above; the framework's export pipeline resolves dotted → IRI via the registry binding in register.go.
IRI strings are spec-rooted at vocabulary/csapi.Namespace. The CS API is still a working draft; when canonical IRIs publish, only these constants need a one-shot swap (the dotted predicates above are framework-internal and don't change).
Variables ¶
This section is empty.
Functions ¶
Types ¶
This section is empty.