Configuring custom artifact types

In addition to the built-in artifact types, Apicurio Registry can be configured at deployment time with custom artifact types. The behavior of a custom type (content detection, validation, compatibility checking, canonicalization, dereferencing) is provided either by webhooks or by Java classes. This chapter describes the configuration file and how to add Java providers to the container image without rebuilding Apicurio Registry.

Artifact type configuration file

The list of artifact types supported by a Apicurio Registry instance is read from a JSON file at startup. The file is configured with the apicurio.artifact-types.config-file property (environment variable APICURIO_ARTIFACT_TYPES_CONFIG_FILE). When the file does not exist, only the built-in artifact types are available.

Example configuration file
{
  "includeStandardArtifactTypes": true,
  "artifactTypes": [
    {
      "artifactType": "MARKDOWN",
      "name": "Markdown",
      "description": "Markdown documents with a level-1 title and level-2 sections.",
      "contentTypes": ["text/markdown", "text/plain"],
      "contentAccepter": {
        "type": "java",
        "classname": "io.apicurio.registry.examples.customtypes.MarkdownContentAccepter"
      },
      "contentValidator": {
        "type": "java",
        "classname": "io.apicurio.registry.examples.customtypes.MarkdownContentValidator"
      },
      "compatibilityChecker": {
        "type": "webhook",
        "url": "https://markdown-service.example.com/compatibility",
        "headers": { "Authorization": "Bearer YOUR_SECRET_TOKEN" }
      }
    }
  ]
}
Table 1. Top-level properties
Property Description

includeStandardArtifactTypes

Whether the built-in artifact types (AVRO, JSON, OPENAPI, …​) remain available. When false, only the types listed in artifactTypes are supported.

artifactTypes

The list of custom artifact types.

Table 2. Artifact type properties
Property Description

artifactType

The identifier of the type, used in the REST API and the UI (for example MARKDOWN). Must be unique.

name, description

Display name and description of the type.

contentTypes

The content types (media types) accepted for this artifact type.

contentAccepter

Provider that decides whether a piece of content belongs to this type. Used to detect the artifact type when a client does not specify one.

contentValidator

Provider that backs the VALIDITY rule (SYNTAX_ONLY and FULL levels).

compatibilityChecker

Provider that backs the COMPATIBILITY rule (BACKWARD, FORWARD, FULL and their transitive variants).

contentCanonicalizer

Provider that produces the canonical form of the content, used to recognize equivalent content (for example canonical search and de-duplication).

contentDereferencer

Provider that inlines or rewrites references to other artifacts when content is retrieved with references=DEREFERENCE or references=REWRITE.

referenceFinder

Provider that finds external references in the content. Used by the Maven plug-in to register references automatically.

Every provider property is optional. When a provider is not configured, the corresponding feature is a no-op for the type (for example, the artifact type is never auto-detected and every content is considered valid and compatible).

Table 3. Provider types
Provider Description

{"type": "java", "classname": "…​"}

A Java class implementing the corresponding interface of the io.apicurio:apicurio-registry-schema-util-common module (io.apicurio.registry.content.ContentAccepter, io.apicurio.registry.rules.validity.ContentValidator, io.apicurio.registry.rules.compatibility.CompatibilityChecker, io.apicurio.registry.content.canon.ContentCanonicalizer, io.apicurio.registry.content.dereference.ContentDereferencer, io.apicurio.registry.content.refs.ReferenceFinder). The class must have a public no-argument constructor and must be available on the class path of Apicurio Registry, see Adding Java providers with the mutable container image.

{"type": "webhook", "url": "…​", "headers": {…​}}

An HTTP endpoint that Apicurio Registry calls with a JSON request describing the operation (content, resolved references, rule level) and that returns a JSON response. The optional headers are sent with every request, for example for authentication. Webhooks work with the standard container image but add a network round trip to every operation.

Adding Java providers with the mutable container image

The standard Apicurio Registry container image is a Quarkus fast-jar: its class path is indexed when the image is built, so a jar copied into the image is not visible to the application. Every release is therefore also published as a VERSION-mutable image, a Quarkus mutable-jar that can be re-augmented to include additional jars. Build a derived image that copies your provider jar into the providers directory and runs the re-augmentation once, at image build time.

Prerequisites
  • A jar containing your provider classes, compiled against the io.apicurio:apicurio-registry-schema-util-common module of the same Apicurio Registry minor version. The jar must not bundle the Apicurio Registry or Quarkus classes; other dependencies must either be already present in the image or be copied into the providers directory as well.

  • An artifact type configuration file, see Artifact type configuration file.

Procedure
  1. Create a Dockerfile that derives from the mutable image:

    FROM apicurio/apicurio-registry:latest-release-mutable
    
    COPY --chown=1001:0 my-artifact-type.jar /deployments/quarkus-app/providers/
    COPY --chown=1001:0 artifact-types.json /deployments/artifact-types.json
    
    RUN /deployments/build.sh --prune
    
    ENV APICURIO_ARTIFACT_TYPES_CONFIG_FILE=/deployments/artifact-types.json

    /deployments/build.sh re-augments the application with the jars found in /deployments/quarkus-app/providers and adds only the regenerated class-path index (a few MB) to the derived image. The --prune option removes the lib/deployment directory (the Quarkus deployment jars) from the file system of the derived image afterwards; omit it if you want to re-augment the derived image again later.

  2. Build and run the image:

    $ docker build -t my-registry .
    $ docker run -it -p 8080:8080 my-registry
  3. Verify that the custom type is available:

    $ curl http://localhost:8080/apis/registry/v3/admin/config/artifactTypes

Re-augmentation takes about ten seconds and requires roughly 1 GB of memory during the image build (tune it with the JAVA_OPTS_APPEND environment variable). It must be repeated, by rebuilding the derived image, whenever the provider jars change. The startup time and runtime behavior of Apicurio Registry are not affected.

Table 4. Trade-offs
Standard image -mutable image

Packaging

Quarkus fast-jar (/deployments)

Quarkus mutable-jar (/deployments/quarkus-app)

Size

Reference

About 47 MB (150 jars) of additional files in lib/deployment (roughly 100 MB of image size with the current image layering). A derived image adds only a few MB; build.sh --prune removes the deployment jars from the file system but, as with any container image, does not shrink the layers inherited from the base image.

Java providers

Not supported (use webhooks)

Supported through /deployments/build.sh

Runtime behavior

Reference

Identical

Additional resources