The project demonstrates how to display and manage data received from an external data source using standard Jmix CRUD screens.
External data for this example is supposed to be provided by a REST service with the following endpoints:
GET /tasks
returns a list of tasksPOST /tasks
creates a new taskPOST /tasks/{id}
updates a task with a given idGET /projects
returns a list of projectsPOST /projects
creates a new projectPOST /projects/{id}
updates a project with a given id
The jmix-samples
repository contains an implementation of such a service in the external-data-service
directory. See its README for how to start the service. By default, it runs on port 18080, so the /tasks
URL will be http://localhost:18080/tasks
.
The first approach to working with external data in UI is to delegate loading and saving entities to a custom service instead of DataManager
which is used by default.
The project contains the Task DTO entity and its browser and editor screens. TaskService makes HTTP requests to external API and maps data to and from DTOs.
The list of DTO entities is loaded to the TaskBrowse screen from TaskService
using the data loader delegate.
Saving of the DTO entity through TaskService
is implemented using the commit delegate in TaskEdit screen.
Another approach for working with external data is to create a custom data store for working with DTO entity. In this case, each time you load or save the DTO entity associated with the custom data store using the DataManager
, the entity will be read/saved by REST services instead of the database.
ProjectDataStore is the custom datastore that saves and loads projects using the REST service. ProjectDataStoreDescriptor is the data store descriptor needed for registering the data store in the application. The custom data store and its descriptor are also registered in application.properties.
The Project DTO entity is associated with this projectds
data store:
@Store(name = "projectds")
@JmixEntity
public class Project {
//...
}
Now you don't have to intercept loading/saving data in screens and redirect to a custom service, because DataManager
will dispatch all requests for the Project
entity to its data store. Each time you work with Project
using the DataManager
the actual job will be done by ProjectDataStore
.
We recommend creating a custom data store for an external data service if the service provides a rich API for working with data: CRUD, paging, sorting, filtering, maybe even a query language. By implementing a data store for such a service you will make it more "native" for development with Jmix. You can inherit your data store from the AbstractDataStore
class (which is used also for built-in JpaDataStore
) and therefore employ the framework mechanisms like security and audit for external data.
If the external service provides just a few simple operations, it's better to use load/commit delegates to bypass DataManager
in UI screens and instead redirect to the service.