/play.remote

a plugin to call JSON API

Primary LanguageJava

A module to call a JSON API via a model definition

The goal of this module is to handle a remote JSON API as a model in the MVC application model.

Enable the module for the application


Configuring the remote server

Configuring access to the remote server is really easy. Just add the host and port of the service in `application.conf`

# Remote server API
remote.host=localhost
remote.port=9011

Configuring routes to remote services

The configuration of the services on the remote server is done in the same way your configure routes in Play!. Create a `conf/remote.conf` file and add the routes as a standard Play! route.

DELETE /api/accounts/{id}		Account.delete
GET /api/accounts/{id}		Account.findById
GET /api/accounts			Account.findAll
GET /api/accounts/{id}/transactions	Transaction.findByAccount
POST 	/api/accounts/{id}/transactions		Transaction.addToAccount
PUT 	/api/transaction/new				Transaction.save

The difference with a standard route file is the the pseudo method are not methods but “called” query to the service assocaited with a stub model. The path to interpret the route file is reversed compared to a standard route file : the call to a pseudo method defined in the route file will call the service on the associated path with the http method of the route.

To see the use of the route file, see “Using your models”.

Defining your model

Defining a (stub) model to a remote service is made by inheriting the RemoteModel and adding the RemoteEntity annotation :

@RemoteEntity
public class Account extends RemoteModel{

	 public Long id;
 	 public Client owner;
    public String number;
    public Double balance;
    public String label;
    
}

Using your models

Using the model is made by passing the names of the pseudo methods to methods defined by the plugin.

Getting a collection of instances of the model

List<Transaction> operations= Transaction.find("findByAccount", id) ;    	

Getting an instance of the model

Special methods

There’s special pseudo methods that can be directly defined in the route file : findById, findAll, delete. The named queries are directly matched to method implemented by the plugin.

To get an instance of an object by id, use the default method findById :

   	Account account = (Account) Account.findById(id);

To get a collection of the instances of the model rendered by a service with no parameter, call the method findAll.

   	List<Account> accounts =  Account.findAll();
        	render("@Application.index", accounts);

To delete

   	HttpResponse response = Account.delete(id);
    	if (response.success()) {
        	render("@Application.index", accounts);    		
    	} else {    	
    		if (response.getStatus().equals(StatusCode.NOT_FOUND)) {
        		String error = 
        				response.getStatusText();
        		render("@Application.index", accounts, error);
    			
    		} else {
    			renderHtml(response.getString());
    		}
    	}

To post/put

The remote plugin respects the distinction of the http verbs PUT and POST. PUT is idempotent, whereas POST is not. Here is an example of the declaration of the routes for PUT and POST verbs.

POST 	/api/accounts/{id}/transactions		Transaction.addToAccount
PUT 	/api/transaction/new				Transaction.save

The PUT verb is called with the special method save. So far, the url can’t have parameters.

The POST verb can be used with any method name. The associated post method of the model has parameters : the name of a pseudo method in the route file, and the parameters value to bind to the url. The following code exposes the difference between the use of the save and post methods of the model.

    public static void saveOperation(@Valid Operation operation) {
        
    	HttpResponse response = operation.save();

    	if (response.success()) {
    		operations(operation.id);
    	} else {    	
   			renderHtml(response.getString());
    	}     
    }

    public static void addOperation(Long id, @Valid Transaction operation) {
        
    	HttpResponse response = operation.post("addToAccount", id);    	

    	if (response.success()) {
    		operations(id);
    	} else {    	
   			renderHtml(response.getString());
    	}     
    }