How to register an interface

Also see:

Suppose you have determined that you need to create a new relation interface called my_fancy_database.

Suppose that your interface specification has the following data model:

  • the requirer app is supposed to forward a list of tables that it wants to be provisioned by the database provider
  • the provider app (the database) at that point will reply with an API endpoint and, for each replica, it will provide a separate secret ID to authenticate the requests

These are the steps you need to take in order to register it with charm-relation-interfaces.

Clone (a fork of) the charm-relation-interfaces repo and set up an interface specification folder

git clone
cd /path/to/charm-relation-interfaces

Make a copy of the template folder

Copy the template folder to a new folder called the same as your interface (with underscores instead of dashes).

cp -r ./interfaces/__template__ ./interfaces/my_fancy_database

At this point you should see this directory structure:

# tree ./interfaces/my_fancy_database
└── v0
    ├── interface.yaml
    ├── interface_tests
2 directories, 3 files

Edit interface.yaml

Add to interface.yaml the charm that owns the reference implementation of the my_fancy_database interface. Assuming your my_fancy_database_charm plays the provider role in the interface, your interface.yaml will look like this:

# interface.yaml
  - name: my-fancy-database-operator  # same as metadata.yaml's .name


Edit to contain:


from interface_tester.schema_base import DataBagSchema
from pydantic import BaseModel, AnyHttpUrl, Field, Json
import typing

class ProviderUnitData(BaseModel):
    secret_id: str = Field(
        description="Secret ID for the key you need in order to query this unit.",
        title="Query key secret ID",

class ProviderAppData(BaseModel):
    api_endpoint: AnyHttpUrl = Field(
        description="URL to the database's endpoint.",
        title="Endpoint API address",

class ProviderSchema(DataBagSchema):
    app: ProviderAppData
    unit: ProviderUnitData

class RequirerAppData(BaseModel):
    tables: Json[typing.List[str]] = Field(
        description="Tables that the requirer application needs.",
        title="Requested tables.",
        examples=[["users", "passwords"]],

class RequirerSchema(DataBagSchema):
    app: RequirerAppData
    # we can omit `unit` because the requirer makes no use of the unit databags

To verify that things work as they should, you can pip install pytest-interface-tester and then run interface_tester discover --include my_fancy_database from the charm-relation-interfaces root.

You should see:

- my_fancy_database:
  - v0:
   - provider:
     - <no tests>
     - schema OK
     - charms:
       - my_fancy_database_charm ( custom_test_setup=no
   - requirer:
     - <no tests>
     - schema OK
     - <no charms>

In particular pay attention to schema. If it says NOT OK then there is something wrong with the pydantic model.


Edit the file to contain:

# `my_fancy_database`

## Overview
This relation interface describes the expected behavior between of any charm claiming to be able to interface with a Fancy Database and the Fancy Database itself.
Other Fancy Database-compatible providers can be used interchangeably as well.

## Usage

Typically, you can use the implementation of this interface from [this charm library](, although charm developers are free to provide alternative libraries as long as they comply with this interface specification.

## Direction
The `my_fancy_database` interface implements a provider/requirer pattern.
The requirer is a charm that wishes to act as a Fancy Database Service consumer, and the provider is a charm exposing a Fancy Database (-compatible API).

flowchart TD
    Requirer -- tables --> Provider
    Provider -- endpoint, access_keys --> Requirer

## Behavior

The requirer and the provider must adhere to a certain set of criteria to be considered compatible with the interface.

### Requirer

- Is expected to publish a list of tables in the application databag

### Provide

- Is expected to publish an endpoint URL in the application databag
- Is expected to create and grant a Juju Secret containing the access key for each shard and publish its secret ID in the unit databags.

## Relation Data

See the [\[Pydantic Schema\]](./

### Requirer

The requirer publishes a list of tables to be created, as a json-encoded list of strings.

#### Example
application_data: {
   "tables": "['users', 'passwords']"

### Provider

The provider publishes an endpoint url and access keys for each shard.

#### Example
application_data: {
   "api_endpoint": ""
units_data : {
  "my_fancy_unit/0": {
     "secret_id": "secret:12312321321312312332312323"
  "my_fancy_unit/1": {
     "secret_id": "secret:45646545645645645646545456"

Add interface tests

This topic is explored in a separate document: How to write interface tests

Open a PR to the charm-relation-interfaces repo

Finally, open a pull request to the charm-relation-interfaces repo and drive it to completion, addressing any feedback or concerns that the maintainers may have.

For reference, here is an example of the result after following this how-to guide.

Contributors: @ppasotti @ironcore864

Last updated 3 days ago. Help improve this document in the forum.