~~NOTRANS~~ ~~Title: REST Storage Client~~ If you need data from a REST service, it's super easy to call the REST service with JVx. The JVx REST services are based on [[https://www.restlet.com/|RESTlet]] and the library should be available in your application as well. To try it out, simply create a unit test: import java.util.List; import java.util.Map; import org.junit.Test; import org.restlet.data.ChallengeScheme; import org.restlet.resource.ClientResource; import com.sibvisions.rad.server.http.rest.JSONUtil; import com.sibvisions.util.type.StringUtil; public class ContactClient { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Test methods //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @Test public void getContacts() throws Exception { ClientResource cres = new ClientResource("https://cloud.sibvisions.com/demoerp/services/rest/DemoERP/Customers/data/customer/"); cres.setChallengeResponse(ChallengeScheme.HTTP_BASIC, "manager", "manager"); List> list = JSONUtil.getObject(cres.get(), List.class); for (Map m : list) { //System.out.println(StringUtil.toString(m.keySet())); System.out.println(m.get("ID") + ": " + m.get("FIRSTNAME") + " " + m.get("SURNAME")); } } } The response is e.g. [ { "ID":730, "COMPANY":"adsad", "FIRSTNAME":"alasafsd", "SURNAME":"asf test", "EMAIL":"sadadsaa", "ADDRESS":"1", "ZIP":"1", "CITY":"2", "CUSTOMERSINCE":"2016-04-30T22:00:00.000+0000", "TITL_ID":1, "TITL_TITLE":"Dr.", "SALU_ID":1, "SALU_SALUTATION":"Male", "CUSTOMER_NR":"CN - 730" }, { "ID":634, "COMPANY":"helDFF", "FIRSTNAME":"Peter", "SURNAME":"Fall", "EMAIL":"oooo", "ADDRESS":"zjr", "ZIP":"1235", "CITY":"www", "CUSTOMERSINCE":"2016-03-09T23:00:00.000+0000", "TITL_ID":1, "TITL_TITLE":"Dr.", "SALU_ID":2, "SALU_SALUTATION":"Female", "CUSTOMER_NR":"CN - 634" }, { "ID":2, "COMPANY":"Excompany", "FIRSTNAME":"ddddd", "SURNAME":"eeee", "EMAIL":"susi.summ@excompany.com", "ADDRESS":"Street 2", "ZIP":"1100", "CITY":"Vienna", "CUSTOMERSINCE":"2012-12-01T23:00:00.000+0000", "TITL_ID":1, "TITL_TITLE":"Dr.", "SALU_ID":1, "SALU_SALUTATION":"Male", "CUSTOMER_NR":"CN - 2" }, { "ID":750, "COMPANY":"333", "FIRSTNAME":"abcefe", "SURNAME":"555", "EMAIL":"Schider.ngai@somehost.com", "ADDRESS":"Far Far Away", "ZIP":"55555", "CITY":"zxcvasd", "CUSTOMERSINCE":null, "TITL_ID":1, "TITL_TITLE":"Dr.", "SALU_ID":1, "SALU_SALUTATION":"Male", "CUSTOMER_NR":"CN - 750" } ] You could integrate the REST call in your business logic, see [[:jvx:communication:calling_server_action|Calling a server-side action]]. If you need the result in your GUI, it's also possible to create a custom storage. We use a simple [[jvx:server:storage:abstract_memory|statful storage]] for our example, but you could also implement a stateless storage. Here's the storage: public class ContactStorage extends AbstractMemStorage { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Initialization //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Creates a new instance of ContactStorage. */ public ContactStorage() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Abstract methods implementation //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @Override public RowDefinition getRowDefinition() throws ModelException { RowDefinition rdef = new RowDefinition(); rdef.addColumnDefinition(new ColumnDefinition("ID", new BigDecimalDataType())); rdef.addColumnDefinition(new ColumnDefinition("FIRST")); rdef.addColumnDefinition(new ColumnDefinition("LAST")); rdef.setPrimaryKeyColumnNames(new String[] {"ID"}); rdef.setColumnView(null, new ColumnView(rdef)); return rdef; } @Override public void loadData(MemDataBook pBook, ICondition pCondition) throws ModelException { pBook.close(); pBook.open(); ClientResource cres = new ClientResource("https://cloud.sibvisions.com/demoerp/services/rest/DemoERP/Customers/data/customer/"); cres.setChallengeResponse(ChallengeScheme.HTTP_BASIC, "manager", "manager"); try { List> list = JSONUtil.getObject(cres.get(), List.class); for (Map m : list) { pBook.insert(false); pBook.setValues(new String[] {"ID", "FIRST", "LAST"}, new Object[] {new BigDecimal((BigInteger)m.get("ID")), m.get("FIRSTNAME"), m.get("SURNAME")} ); } pBook.saveAllRows(); } catch (IOException ioe) { throw new ModelException(ioe); } } @Override public void insert(DataBookEvent pEvent) throws ModelException { } @Override public void update(DataBookEvent pEvent) throws ModelException { } @Override public void delete(DataBookEvent pEvent) throws ModelException { } } Our storage doesn't support insert/update/delete/filtering/sort. Only fetching data is implemented. But if you use client filtering/sort, it will work well. The storage is ready to use with life-cycle objects: public IStorage getContacts() throws Exception { ContactStorage storage = (ContactStorage)get("contacts"); if (storage == null) { storage = new ContactStorage(); storage.open(); put("contacts", storage); } return storage; } And on the client side, use a RemoteDataBook as usual: RemoteDataBook rdbContacts = new RemoteDataBook(); rdbContacts.setName("contacts"); rdbContacts.setDataSource(getDataSource()); //because our storage doesn't support remote filtering/sort rdbContacts.setMemFilter(true); rdbContacts.setMemSort(true); rdbContacts.open(); And here's an example application: {{ :jvx:contacts.png?nolink |}} \\ **Note** It's also possible to use other REST libraries, like: * https://howtoprogram.xyz/java-technologies/java-rest-client-example/ * https://stackoverflow.com/questions/221442/rest-clients-for-java Using RESTlet may be an option because it's used from JVx and thanks to JSONUtil it's easy to access the JSON object from the Response.