Database service interface

Defining a service interface is as simple as defining a Java interface, except that there are certain rules to respect for code generation to work and also to ensure inter-operability with other code in Vert.x.

The beginning of the interface definition is:

  1. @ProxyGen
  2. @VertxGen
  3. public interface WikiDatabaseService {
  4. @Fluent
  5. WikiDatabaseService fetchAllPages(Handler<AsyncResult<JsonArray>> resultHandler);
  6. @Fluent
  7. WikiDatabaseService fetchPage(String name, Handler<AsyncResult<JsonObject>> resultHandler);
  8. @Fluent
  9. WikiDatabaseService createPage(String title, String markdown, Handler<AsyncResult<Void>> resultHandler);
  10. @Fluent
  11. WikiDatabaseService savePage(int id, String markdown, Handler<AsyncResult<Void>> resultHandler);
  12. @Fluent
  13. WikiDatabaseService deletePage(int id, Handler<AsyncResult<Void>> resultHandler);
  14. // (...)
  1. The ProxyGen annotation is used to trigger the code generation of a proxy for clients of that service.

  2. The Fluent annotation is optional, but allows fluent interfaces where operations can be chained by returning the service instance. This is mostly useful for the code generator when the service shall be consumed from other JVM languages.

  3. Parameter types need to be strings, Java primitive types, JSON objects or arrays, any enumeration type or a java.util collection (List / Set / Map) of the previous types. The only way to support arbitrary Java classes is to have them as Vert.x data objects, annotated with @DataObject. The last opportunity to pass other types is service reference types.

  4. Since services provide asynchronous results, the last argument of a service method needs to be a Handler<AsyncResult<T>> where T is any of the types suitable for code generation as described above.

It is a good practice that service interfaces provide static methods to create instances of both the actual service implementation and proxy for client code over the event bus.

We define create as simply delegating to the implementation class and its constructor:

  1. @GenIgnore
  2. static WikiDatabaseService create(JDBCClient dbClient, HashMap<SqlQuery, String> sqlQueries, Handler<AsyncResult<WikiDatabaseService>> readyHandler) {
  3. return new WikiDatabaseServiceImpl(dbClient, sqlQueries, readyHandler);
  4. }

The Vert.x code generator creates the proxy class and names it by suffixing with VertxEBProxy. Constructors of these proxy classes need a reference to the Vert.x context as well as a destination address on the event bus:

  1. @GenIgnore
  2. static WikiDatabaseService createProxy(Vertx vertx, String address) {
  3. return new WikiDatabaseServiceVertxEBProxy(vertx, address);
  4. }
Note
The SqlQuery and ErrorCodes enumeration types that were inner classes in the previous iteration have been extracted to package-protected types, see SqlQuery.java and ErrorCodes.java.