Skip to content

Implementation Guidelines for Requests, Responses and Events

Matthew Horridge edited this page Oct 18, 2023 · 11 revisions

This page provides some details on naming conventions for Requests, Responses and Events.

Requests are messages delivered through message channels. Each request type is associated with a unique channel name. Therefore, RequestX will have a distinct channel name from RequestY.

Responses are also messages delivered via message channels. The channel name for a response is derived from the associated request channel. This is derived by appending "-replies" to the request channel name.

Events are messages delivered through message channels as well. Each event type has its own unique channel name. Hence, EventX will have a different channel name compared to EventY.

Requests

  • A Request object is message object that is used to make a request.
  • Java records are ideal for implementing requests.
  • Requests should implement either the Request interface (edu.stanford.protege.webprotege.common.Request) or the more specific ProjectRequest interface (edu.stanford.protege.webprotege.common.ProjectRequest).
  • The Java record that implements the Request should have a name that is suffixed with "Request". For example, "GetSomethingRequest".
  • Each field in the implementing record should be annotated with a @JsonProperty annotation.
  • Each type of request has a specific channel name. For builtin WebProtege requests this name should be prefixed with webprotege. and the suffix should be the the name of the Java record without the "Request" suffix. For example, for "GetSomethingRequest" the channel name could be "webprotege.myrequests.GetSomething".
  • The channel name should be stored in a field constant (public static final String) named CHANNEL.
  • Each implementing Java record MUST be annotated with the Jackson @JsonTypeName annotation and this should have a value that is equal to the request channel name. The CHANNEL constant can be used for the value of the @JsonTypeName annotation.

The Java record below shows an example request.

@JsonTypeName(CHANNEL)
public record CreateSnapshotRequest(@JsonProperty("projectId") ProjectId projectId,
                                    @JsonProperty("revisionNumber") RevisionNumber revisionNumber,
                                    @JsonProperty("documentFormat") DocumentFormat documentFormat,
                                    @JsonProperty("fileName") String fileName) implements ProjectRequest<CreateSnapshotResponse> {

    public static final String CHANNEL = "webprotege.snapshots.CreateSnapshot";

    @Override
    public String getChannel() {
        return CHANNEL;
    }
}

Responses

  • A Response object is a message object that is used to reply to a request.
  • Java records are ideal for implementing responses.
  • Responses should implement the Response interface (edu.stanford.protege.webprotege.common.Response)
  • The Java record that implements the Response should have a name that is suffixed with "Response". For examle, "GetSomethingResponse".
  • Each field in the implementing record should be annotated with a @JsonProperty annotation.
  • Each implementing Java record MUST be annotated with the Jackson @JsonTypeName annotation and this should have a value that is equal to the response channel name.

The Java record below shows an implementation of a response (to the above request).

@JsonTypeName("webprotege.snapshots.CreateSnapshot")
public record CreateSnapshotResponse(@JsonProperty("snapshotStorageCoordinates") SnapshotStorageCoordinates snapshotStorageCoordinates) implements Response {

}

Events

  • An Event object is a message object that represents some event.
  • Java records are ideal for implementing events.
  • Events should implement either the Event interface (edu.stanford.protege.webprotege.common.Event) or the more specific ProjectEvent interface (edu.stanford.protege.webprotege.common.ProjectEvent`). Project events are events that pertain to specific WebProtege projects and this more specific interace should be implemented for project events.
  • The Java record that implements the Event should have a name that is suffixed with "Event", for example, "SomethingHappenedEvent".
  • Each type of event has an associated unique channel for the type. For buitin WebProtege events the name of the channel should be prefixed with "webprotege.events." and end with the name of the event but should NOT include the "Event" suffix, for example, "webprotege.events.SomethingHappened".
  • The channel name should be stored in a field constant (public static final String) named CHANNEL.
  • Each implementing Java record MUST be annotated with the Jackson @JsonTypeName annotation and this should have a value that is equal to the channel name. The CHANNEL constant can be used for the value of the @JsonTypeName annotation.
@JsonTypeName(CHANNEL)
public record DiscussionThreadCreatedEvent(EventId eventId,
                                           ProjectId projectId,
                                           EntityDiscussionThread discussionThread) implements ProjectEvent {

    public static final String CHANNEL = "webprotege.events.discussions.DiscussionThreadCreated";

    @Override
    public String getChannel() {
        return CHANNEL;
    }
}

Overall Naming Coordination

In summary, for some operation/action CreateWidget there could be three Java records (or classes): CreateWidgetRequest, CreateWidgetResponse and WidgetCreatedEvent. The channel name for the request could be webprotege.widgets.CreateWidget and the chanel name for the events could be webprotege.events.widgets.WidgetCreated.