Extension points
Experimental feature
This feature is highly experimental and may not work correctly in all instances. Proceed at your own risk.
Extension points allow you to specialize existing building blocks by constraining or customizing their referenced components. This mechanism enables developers to create tailored versions of standard building blocks while maintaining compatibility with the original specifications.
An extension point consists of:
- A base building block that you want to extend.
- A set of mappings from referenced building blocks in the base (or its imports) to your custom building blocks.
OpenAPI building blocks
For building blocks backed by an OpenAPI document rather than a standalone JSON Schema, extension points produce a real, merged OpenAPI document — same as the JSON Schema case, but working against the shape of an OpenAPI document instead of a bare schema:
paths,webhooksandcomponents.*entries from your ownopenapi.yamlare added to the base document. Redeclaring a key that already exists in the base overrides it in place (a warning is logged, since this is also plausibly an accidental collision). Set an entry tofalseinstead of an object to remove one inherited from the base — removing an entry that doesn’t exist is still an error.info,servers,security,tagsandexternalDocs, if declared in youropenapi.yaml, replace the base’s values outright (whole-value overrides, not merges).- Every schema reference in the base document (in
paths,webhooks, orcomponents) that transitively points at one of yourextensionsmappings’fromBuildingBlockis substituted the same way as in the JSON Schema case — including references nested inside a Parameter, Response, RequestBody, Header, Example or Link object, not just bare Schema Object slots. - A base document written for OpenAPI 3.0 is automatically upconverted to 3.1 first, since substitution depends on 2020-12 JSON Schema alignment.
Upgrading from bblocks-postprocess before v1.1.0
Before v1.1.0, OpenAPI extension points were declarative only — recorded in the register, but no document
was actually produced. If you declared extensionPoints against an OpenAPI building block before
upgrading, its OpenAPI document is now compiled for the first time; review it once after upgrading. (This
notice will be removed once this is no longer a recent change.)
This approach ensures that any references in the base schema (or recursively in its imports) to a given building block are further constrained to conform to your specialized version.
For example: if a base FeatureCollection building block references a Feature building block, and you
need a collection that only accepts your specialized MyFeature type, you declare an extension mapping
Feature → MyFeature. The postprocessor then produces a compiled schema for your extension in which
every reference to Feature in the base — including references buried inside imported building blocks —
is constrained to also satisfy MyFeature. Consumers can validate against that single compiled schema
without needing to understand the extension relationship at all.
Extension points also preserve semantic mappings in building blocks and inherit SHACL validation shapes from both the base building block and the targets for the extensions — the base and every extension source/target are automatically added as dependencies of the extension, and SHACL shape inheritance follows dependencies. There is currently no way to opt out of this inheritance.

Why Use Extension Points?
- Customization: Adapt standard building blocks to your domain-specific requirements.
- Consistency: Maintain compatibility with OGC standards while introducing specialized semantics.
- Reusability: Avoid duplicating entire schemas; only override what you need.
- Convenience: The postprocessor compiles a single, self-contained schema document — no need to chain multiple schemas together at validation time.
How It Works
When you declare an extension point:
- You specify a base building block.
- You provide a set of from → to mappings:
- fromBuildingBlock: A building block referenced by the base.
- toBuildingBlock: Your specialized version of that building block.
Any schema references to fromBuildingBlock in the base (or its imported building blocks)
will be constrained to also satisfy the schema of toBuildingBlock.
Example Scenario
- Base:
FeatureCollection - Referenced Block:
Feature - Custom Mapping:
Feature → MyFeature
Result:
- You create a custom
MyFeatureCollectionthat contains elements valid as bothFeatureandMyFeature.
Declaration Format
Extension points are declared in the bblock.json file using the following structure:
{
"...": "...",
"extensionPoints": {
"baseBuildingBlock": "ogc.ogc-utils.prov",
"extensions": {
"ogc.ogc-utils.prov-entity": "ogc.sandbox.extensions.featureExt"
}
}
}
baseBuildingBlock: The identifier of the building block you are extending.extensions: A key-value map where:- Key: Identifier of the referenced building block in the base.
- Value: Identifier of your specialized building block.
The example above ensures that wherever prov-entity appears in the base or its imports,
it will be constrained to also satisfy featureExt. The generated JSON-LD context for the extension
will also include any mappings coming from featureExt.
Extension points cannot target schema fragments
baseBuildingBlock and every key/value in extensions must be a full building block identifier — none of
them may contain a # fragment. Declaring an extension point against a $defs entry or other fragment of a
building block’s schema is not supported and will fail postprocessing.