Configuring content and structure searches

You can connect Apicurio Registry to Elasticsearch to find artifact versions by their content or structural elements, such as schema names, fields, and operations.

Content and structure searches are experimental. Their configuration and behavior can change between releases.

Content and structure search

Content search matches words in artifact content. Structure search matches elements that Apicurio Registry extracts from that content, such as an OpenAPI schema named Order or a Protobuf message named Customer.

Apicurio Registry stores artifact data in its configured storage and maintains a separate search index in Elasticsearch. Elasticsearch does not replace the primary storage. Only searches that include a content or structure filter use the search index. Searches that use only metadata filters continue to use the primary storage.

The search index contains artifact version content and metadata. Protect access to Elasticsearch with the same care as access to Apicurio Registry storage.

Index updates run asynchronously after changes to artifacts. Search results can lag behind writes and deletions. Content and structure searches require an available search index and do not fall back to metadata search when Elasticsearch is unavailable.

Enabling content search

You can enable the search index on an existing Apicurio Registry deployment by configuring an Elasticsearch connection and restarting the application.

Prerequisites
  • You have installed Apicurio Registry.

  • You have an Elasticsearch cluster that the Apicurio Registry application can reach. Its version is compatible with the Elasticsearch Java client included in your Apicurio Registry release.

  • You have access to the deployment configuration and Elasticsearch credentials, if authentication is enabled.

Procedure
  1. Add the following environment variables to the Apicurio Registry application configuration:

    APICURIO_FEATURES_EXPERIMENTAL_ENABLED=true
    APICURIO_SEARCH_INDEX_ENABLED=true
    QUARKUS_ELASTICSEARCH_HOSTS=elasticsearch:9200

    Replace elasticsearch:9200 with the hostname and port of your Elasticsearch cluster. For multiple hosts, use a comma-separated list.

  2. If Elasticsearch requires authentication, configure QUARKUS_ELASTICSEARCH_USERNAME and supply QUARKUS_ELASTICSEARCH_PASSWORD from your deployment’s secret management system.

    For an HTTPS connection, configure QUARKUS_ELASTICSEARCH_PROTOCOL=https and the certificate trust settings for your Elasticsearch client. Match these settings to the cluster configuration.

  3. Restart the Apicurio Registry application to apply the configuration.

Verification
  • Check the application logs for Elasticsearch search index ENABLED and any connection or indexing errors.

  • Submit a content or structure search for an existing artifact version after the initial index build. Confirm that the expected version is in the results.

Trying content search with Docker Compose

You can run Apicurio Registry and Elasticsearch locally to evaluate content search before you configure an existing deployment.

Prerequisites
  • You have installed Docker and Docker Compose.

  • You have selected a Apicurio Registry container image version.

Procedure
  1. Create a compose.yaml file with the following content:

    services:
      elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:9.2.3
        environment:
          discovery.type: single-node
          xpack.security.enabled: "false"
          ES_JAVA_OPTS: "-Xms512m -Xmx512m"
        healthcheck:
          test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health || exit 1"]
          interval: 10s
          timeout: 5s
          retries: 10
      registry:
        image: apicurio/apicurio-registry:VERSION
        environment:
          APICURIO_FEATURES_EXPERIMENTAL_ENABLED: "true"
          APICURIO_SEARCH_INDEX_ENABLED: "true"
          QUARKUS_ELASTICSEARCH_HOSTS: "elasticsearch:9200"
          APICURIO_SEARCH_INDEX_ELASTICSEARCH_NUMBER_OF_REPLICAS: "0"
        ports:
          - "127.0.0.1:8080:8080"
        depends_on:
          elasticsearch:
            condition: service_healthy

    Replace VERSION with the container image version. The Apicurio Registry 3.4 build includes the Elasticsearch 9.2.3 Java client and supports Elasticsearch 9.x servers; use a server version that is the same as or newer than the client within the 9.x series. For another Apicurio Registry release, select an Elasticsearch version compatible with its Java client. This local example uses in-memory registry storage and disables Elasticsearch authentication. It is intended for evaluation; it does not preserve registry data when you recreate the container.

  2. Start the services:

    docker compose up -d
  3. Check the application logs:

    docker compose logs registry
Verification

Configuring content search with the Apicurio Registry Operator

You can configure the Elasticsearch connection in the spec.app.searchIndex section of an ApicurioRegistry3 custom resource.

Prerequisites
  • You have installed the Apicurio Registry Operator and created an ApicurioRegistry3 custom resource.

  • You have an Elasticsearch cluster that the Apicurio Registry application pods can reach.

  • You have created a secret containing the Elasticsearch password in the same namespace as the custom resource, if Elasticsearch requires authentication.

Procedure
  1. Add the search index configuration to your existing registry.yaml custom resource file:

    apiVersion: registry.apicur.io/v1
    kind: ApicurioRegistry3
    metadata:
      name: my-registry
    spec:
      app:
        searchIndex:
          enabled: true
          hosts: "elasticsearch:9200"
          indexName: "apicurio-registry"
          username: "registry-search"
          password:
            name: elasticsearch-credentials
            key: password

    Preserve your existing storage and deployment settings. Replace the hostname, username, and secret reference with your values. Omit username and password if your cluster does not require authentication.

    The Apicurio Registry Operator sets the environment variables for experimental features, search indexing, the Elasticsearch hosts, and any supplied credentials and index name. The password reference uses name and key directly under password.

  2. If your cluster requires HTTPS, add the client protocol and certificate trust settings to your existing spec.app.podTemplateSpec configuration.

    For example, set the protocol on the application container:

    spec:
      app:
        podTemplateSpec:
          spec:
            containers:
              - name: apicurio-registry-app
                env:
                  - name: QUARKUS_ELASTICSEARCH_PROTOCOL
                    value: https
  3. Apply the updated custom resource:

    kubectl apply -f registry.yaml
Verification
  • Check the application pod logs for connection or indexing errors, then search for an existing artifact version.

Searching version content with the REST API

You can use the content and structure query parameters on GET /apis/registry/v3/search/versions to find versions by their content and combine the results with metadata filters.

Prerequisites
  • You have enabled the search index and indexed artifact versions.

  • You have the Apicurio Registry API URL and permission to search versions.

  • You have installed curl.

Procedure
  1. Set the API URL for your deployment:

    export REGISTRY_URL=http://localhost:8080/apis/registry/v3
  2. Search for versions whose content includes customer:

    curl --get "$REGISTRY_URL/search/versions" \
      --data-urlencode 'content=customer'

    For a deployment that requires authentication, include the authentication headers that your deployment uses. If the query contains several words, all query terms must match the indexed content.

  3. Search for OpenAPI versions that define a schema named Order:

    curl --get "$REGISTRY_URL/search/versions" \
      --data-urlencode 'structure=openapi:schema:Order'
  4. To narrow the results, combine content and structure filters with metadata filters:

    curl --get "$REGISTRY_URL/search/versions" \
      --data-urlencode 'content=payment' \
      --data-urlencode 'structure=schema:Invoice' \
      --data-urlencode 'artifactType=OPENAPI' \
      --data-urlencode 'groupId=payments'

    The request returns versions that satisfy all of the filters. You can also set limit and offset to page through the results.

Verification
  • Check the versions array and count in the response. An empty versions array means that no indexed versions match the filters on the requested page.

Troubleshooting
  • If the response error message is Content search requires the search index, which is not enabled., the search index feature is not enabled. Enable and configure the index as described in this chapter.

  • If the response error message is Content search requires the Elasticsearch search index, which is not available., the index is enabled but startup indexing has not finished. Allow startup indexing to complete and repeat the search.

  • If a recent change is missing from the results, allow time for the asynchronous index update and repeat the search. Check the application logs if the results remain incomplete.

Searching version content in the web console

You can use the Content and Structure filters in the web console to search artifact versions without writing a REST request.

Prerequisites
  • You have enabled the search index and indexed artifact versions.

  • You have access to the Apicurio Registry web console.

Procedure
  1. Open the Search page.

  2. In the Search for field, select Versions.

  3. In the filter selector, select Content or Structure.

  4. Enter a search value, such as customer for content or openapi:schema:Order for structure, and press Enter to add the filter.

  5. Optional: Add metadata filters, such as Type or Group, to narrow the results.

Verification
  • Check that the results include the expected artifact versions. Use Refresh to repeat the search after an index update.

Troubleshooting
  • If Content and Structure are unavailable, confirm that you selected Versions and that the application has search indexing enabled.

Structure search formats

The structure filter accepts an exact element identifier or a text query. The format determines how Elasticsearch matches the query against extracted elements.

Table 1. Structure filter formats
Format Example Behavior

type:kind:name

openapi:schema:Order

Matches the complete element identifier after conversion to lowercase. The artifact type, element kind, and name must match. The name can contain additional colons.

kind:name

schema:Order

Searches the extracted element text for both schema and Order across artifact types. This is a text search, not an exact element identifier match.

name

Order

Searches the extracted element text across artifact types and element kinds.

Artifact type identifiers in exact queries use the registry type name, such as json, protobuf, or agent_card. For example, json:property:customerId matches a JSON Schema property named customerId.

Searchable structural elements

Each artifact type defines the structural elements that Apicurio Registry extracts for search. Use the element kinds with the structure filter to narrow a query.

Table 2. Artifact types and extracted element kinds
Artifact type identifier Element kinds

AGENT_CARD

skill, capability, inputmode, outputmode, protocolbinding, protocolversion, url, securityscheme, tag

ASYNCAPI

channel, message, schema, operation, tag, server, parameter, security_scheme

AVRO

name, field, type, enum_symbol, namespace

GRAPHQL

type, field, enum, input, interface, union, directive

ICEBERG_TABLE

name, column, partition, sort

ICEBERG_VIEW

name, column, sql

JSON

id, property, definition, required

MCP_TOOL

parameter

MODEL_SCHEMA

modelid, provider, inputproperty, outputproperty

OPENAPI

schema, path, operation, tag, parameter, security_scheme, server

PROMPT_TEMPLATE

templateid, variable, outputproperty

PROTOBUF

package, message, field, enum, service, rpc

THRIFT

namespace, struct, enum, union, exception, service, typedef, const

WSDL

service, port, binding, portType, operation, message, element, complexType, simpleType

XML

element, namespace

XSD

element, complexType, simpleType, attribute, attributeGroup, group

Extraction depends on the content and format. For example, OpenAPI schema names come from component definitions, and XSD type names come from top-level schema declarations. Types without a structured extractor, and content that an extractor cannot parse, have no extracted elements. Their raw content remains available for content search, subject to the content size limit.

Search index configuration

You can configure the search index name, shard counts, and content size limit independently of the primary storage settings.

Table 3. Search index properties
Property Default Description

apicurio.features.experimental.enabled

false

Experimental feature setting. Set to true when configuring content search.

apicurio.search.index.enabled

false

Enables indexing and content and structure searches.

apicurio.search.index.elasticsearch.index-name

apicurio-registry

Name of the Elasticsearch index. Use separate index names for independent registry deployments.

apicurio.search.index.elasticsearch.number-of-shards

1

Number of primary shards when Apicurio Registry creates the index.

apicurio.search.index.elasticsearch.number-of-replicas

1

Number of replica shards when Apicurio Registry creates the index. The local single-node example uses 0.

apicurio.search.index.content.max-size

1048576

Maximum number of characters from each artifact version to index for content search. This limit does not change stored artifact content.

Elasticsearch connection properties use the quarkus.elasticsearch prefix. The connection settings include hosts, protocol, username, and password. Apicurio Registry disables the Quarkus Elasticsearch health check by default and provides a separate readiness check for startup indexing.

Search index operation and limitations

The search index is a secondary copy of registry data. Index updates and rebuilds affect when artifact versions become visible in content and structure searches.

On startup, Apicurio Registry creates the index if necessary. If the index contains no artifact versions, Apicurio Registry rebuilds it from primary storage. A distributed lock in Elasticsearch selects one registry replica to run the startup rebuild. Other replicas skip that rebuild, so their search results can be incomplete until indexing finishes.

When an upgrade changes the index mapping version, Apicurio Registry deletes and recreates the search index before rebuilding it. The primary storage retains artifact data. Rebuilding a large index can extend startup time. Check the logs for indexing errors and verify representative search results after a rebuild; application readiness alone does not confirm that every version was indexed.

During normal operation, a background worker processes index updates. The delay before results reflect a change depends on the indexing workload and Elasticsearch refreshes. A successful artifact write does not confirm that its search index update has completed.

Edits to draft version content do not currently trigger an index update. Finalizing the draft triggers reindexing of that version. Until then, content and structure searches can continue to match the content from before the edit.

For content search, Apicurio Registry indexes only the first apicurio.search.index.content.max-size characters of each version. The default is 1,048,576 characters. Terms beyond that limit do not match a content query. Structured extraction receives the complete artifact content and is separate from this truncation.