Previously, the Confluent Schema Registry only allowed you to manage Avro schemas. With Confluent Platform 5.5, the schema management within Schema Registry has been made pluggable, so that custom schema types can be added. In addition, schema plugins have been developed for both Protobuf and JSON Schema.
Now Schema Registry has two main extension points:
- REST Extensions
- Schema Plugins
In reality, the schema management within Schema Registry is really just a versioned history mechanism, with specific rules for how versions can evolve. To demonstrate both of the above extension points, I’ll show how Confluent Schema Registry can be turned into a full-fledged chess engine.1
A Schema Plugin for Chess
A game of chess is also a versioned history. In this case, it is a history of chess moves. The rules of chess determine whether a move can be applied to a given version of the game.
To represent a version of a game of chess, I’ll use Portable Game Notation (PGN), a format in which moves are described using algebraic notation.
However, when registering a new version, we won’t require that the client send the entire board position represented as PGN. Instead, the client will only need to send the latest move. When the schema plugin receives the latest move, it will retrieve the current version of the game, check if the move is compatible with the current board position, and only then apply the move. The new board position will be saved in PGN format as the current version.
So far, this would allow the client to switch between making moves for white and making moves for black. To turn Schema Registry into a chess engine, after the schema plugin applies a valid move from the client, it will generate a move for the opposing color and apply that move as well.
In order to take back a move, the client just needs to delete the latest version of the game, and then make a new move. The new move will be applied to the latest version of the game that is not deleted.
Finally, in order to allow the client to play a game of chess with the black pieces, the client will send a special move of the form {player as black}
. This is a valid comment in PGN format. When this special move is received, the schema plugin will simply generate a move for white and save that as the first version.
Let’s try it out. Assuming that the chess schema plugin has been built and placed on the CLASSPATH for the Schema Registry2, the following properties need to be added to schema-registry.properties
3
schema.providers=io.yokota.schemaregistry.chess.schema.ChessSchemaProvider resource.static.locations=static resource.extension.class=io.yokota.schemaregistry.chess.SchemaRegistryChessResourceExtension
The above properties not only configure the chess schema plugin, but also the chess resource extension that will be used in the next section. Once Schema Registry is up, you can verify that the chess schema plugin was registered.
$ curl http://localhost:8081/schemas/types ["CHESS","JSON","PROTOBUF","AVRO"]
Let’s make the move d4
.
$ curl -X POST -H "Content-Type: application/vnd.schemaregistry.v1+json" \ --data '{"schema": "d4", "schemaType": "CHESS"}' \ http://localhost:8081/subjects/newgame/versions {"id":1}
Schema Registry returns the ID of the new version. Let’s examine what the version actually looks like.
$ curl http://localhost:8081/subjects/newgame/versions/latest { "subject": "newgame", "version": 1, "id": 1, "schemaType": "CHESS", "schema": "1.d4 d5" }
Schema Registry replied with the move d5
.
We can continue playing chess with Schema Registry in this fashion, but of course it isn’t the best user experience. Let’s see if a REST extension will help.
A REST Extension for Chess
A single-page application (SPA) with an actual chess board as the interface would provide a much better experience. Therefore, I’ve created a REST Extension that wraps a Vue.js SPA for playing chess. When the user makes a move on the chess board, the SPA sends the move to Schema Registry, retrieves the new board position, determines the last move played by the computer opponent, and makes that move on the board as well.
With the REST extension configured as described in the previous section, you can navigate to http://localhost:8081/index.html to see the chess engine UI presented by the REST extension. When playing a chess game, the game history will appear below the chess board, showing how the board position evolves over time.
Here is an example of the REST extension in action.
As you can see, schema plugins in conjunction with REST extensions can provide a powerful combination. Hopefully, you are now inspired to customize Confluent Schema Registry in new and creative ways. Have fun!
- The source code can be found at https://github.com/rayokota/schema-registry-chess-engine
- This will be
${CONFLUENT_HOME}/share/java/schema-registry
for a Confluent 5.5 installation. If running Schema Registry from master, you can place the jar for the plugin inpackage-schema-registry/target/kafka-schema-registry-package-X.X.X-SNAPSHOT-development/share/java/schema-registry/
- The properties file is at
${CONFLUENT_HOME}/etc/schema-registry/schema-registry.properties
for a Confluent installation. If running Schema Registry from master, it is atconfig/schema-registry.properties
.