REST APIs

Many of the IDE components that you build into your extension will need to communicate directly with the Che server or to the workspace the IDE is currently bound to. Che provides helper utilities to make REST calls simpler. Che’s REST library is built on top of Google’s HTTP Java client libraries.

In your extension code, you can create an AsyncRequestFactory object, which has helper methods for creating requests that will have responses.

che/core/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/ProjectTypeServiceClientImpl.java

private void getProjectType(@NotNull String workspaceId,
                            @NotNull String id,
                            @NotNull AsyncCallback<ProjectTypeDto> callback) {

    final String url = extPath + "/project-type/" + workspaceId + '/' + id;
    asyncRequestFactory.createGetRequest(url)
                       .header(ACCEPT, APPLICATION_JSON)
                       .loader(loaderFactory.newLoader("Getting info about project type..."))
                       .send(newCallback(callback,
                                         dtoUnmarshallerFactory.newUnmarshaller(ProjectTypeDto.class)));

}

This example comes from the class used by the IDE to ask the server to provide a response on what the current project type is within the currently active workspace. The asyncRequestFactory object was instantiated by the system as an input parameter. Calling the createGetRequest() method with the GET REST URL as an input will generate a request and a response. The .loader() method is an optional display component that will appear on the screen while the contents of the response are loading. The send() method takes a callback object which will be invoked by the system when a response is delivered.

In the debugger implementation class, you can see a range of REST calls for different individual functions such as step into, step over, and so forth.

In the Java content assist class, you can see the sequence of REST calls that are made for generating requests for information from the server about intellisense features that can only be processed on the server side.

Callbacks

In Che, you will frequently see AsyncRequestCallback<T> objects passed into an AsyncRequestFactory object. Callbacks will be invoked by the system when a response is returned. This class inherits from com.google.gwt.http.client.RequestCallback and we add in a few additional objects:

  1. Unmarshallable<T> which is logic to convert the response payload from data into a Java object.
  2. AsyncRequestLoader which is a visual loader to display while downloading data.
  3. AsyncRequest which is the original request.

Che provides different types of Unmarshallable objects including StringUnmarshaller, StringMapUnmarshaller, StringMapListUnmarshaller, DtoUnmarshaller, and LocationUnmarshaller. These different marshallers represent the most common types of JSON to Java payload conversions.

For example, this logic comes from the git plugin and is the method that is called when a user asks to delete the local git repository contained within the project.

che/plugins/plugin-git/che-plugin-git-ext-git/src/main/java/org/eclipse/che/ide/ext/git/client/delete/DeleteRepositoryPresenter.java

public void deleteRepository() {
    final CurrentProject project = appContext.getCurrentProject();
    final GitOutputConsole console = gitOutputConsoleFactory.create(DELETE_REPO_COMMAND_NAME);

     service.deleteRepository(workspaceId, project.getRootProject(),
                              new AsyncRequestCallback<Void>() {
        @Override
        protected void onSuccess(Void result) {
            console.print(constant.deleteGitRepositorySuccess());
            consolesPanelPresenter.addCommandOutput(appContext.getDevMachineId(), console);
            notificationManager.notify(constant.deleteGitRepositorySuccess(), project.getRootProject());
            getRootProject(project.getRootProject());
        }

        @Override
        protected void onFailure(Throwable exception) {
            // The logic for what to do if the response generated a failure message
        }
    });
}

In this example, the service.deleteRepository(...) is a method that will generate the AsyncRequestFactory object for calling the server. This object requires a AsyncRequestCallback<T>. This method creates a new instance inline with a callback that expects the response to send data of Void type, which basically means that there is no response payload. In this case, either the server tells us there is success or there is failure. The AsyncRequestCallback instance needs to implement two methods onSuccess(<T>) and onFailure(Throwable), which will be called by the AsyncRequestFactory when the response arrives on the wire. It is within these methods that the logic is placed that tells the IDE what to do in each event.