Jump to: navigation, search

REST support in STP

Revision as of 23:06, 18 November 2007 by Johnson.ma.iona.com (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Introduction

This page aims to define the basic processes on how to support REST in stp, there is sample to simplifies how to create a RESTfull service from a database directly.

There are two ways to support to create RESTfull service:

* Exposing a database to RESTfull service directly
* Starting from importing some POJO class into a rest project

Exposing a database to RESTfull service directly

We can create a RESTfull service by starting from a database with the following steps:

Create a REST project using STP.Service Creation Wizard

add project nature "org.eclipse.jem.workbench.JavaEMFNature" which defined in WTP DALI subproject and Java Persistence Facet, once the project has the nature and JP Facet, some DALI function will be available in the subsequent steps.

Generate Entity classes from database

select a database to connect

Connect.JPG

select tables that want to be exposed as REST resource from the databse

Tables.JPG

the following classes will be generated:

Entities class.JPG

three entities class will be generated, these classes are annotated with JPA annotations(by the way, the used JPA implementation library is Oracle TopLink), users can modify the annotations in the generated classes through JPA detail view, it looks like:

Jpa detail.JPG

add all entity classes into a persistence unit by configuring persistence.xml

What STP REST tool will do

WTP Dali project provides the functiona of entity classes generation from database, the STP REST project will focus on how to wrap these entity classes into Resource classes, deploy REST project and generate test client to test deployed REST server , the following work will be done by STP REST tool,

Generate Resources class for each entity class

In this step, we will provide a tool for generating Resource class from entity classes. User select the entity classes that generated from database to generate resource classes ,all these resource classes are annotated with annotations defined in jsr311 specification. each entity class maps to two Resource classes, for example, Item class has ItemResource class and ItemsResource class, ItemResource class responsible for getting detail info of a specific item, updating and deleting the item, ItemsResource class is responsible for returning Item list and adding a new item. After resource classes are generated, the project package view looks like:

Rest packagesrtucture.JPG


Entity class com.iona.entities.Item looks like:

//Item.java
@Entity
@Table(schema="test")
public class Item implements Serializable {
	@Id
	private long sku;
	private String description;
	private String name;
	private int version;
	private String category;
	@OneToMany(mappedBy="item")
	private Set<Order> orderTableCollection;
	@OneToMany(mappedBy="item")
	private Set<Inventory> inventoryCollection;
	private static final long serialVersionUID = 1L;
	public Item() {
		super();
	}
	public long getSku() {
		return this.sku;
	}
	public void setSku(long sku) {
		this.sku = sku;
	} 
....


Resource com.iona.resources.ItemsResource :

//ItemsResource.java
@UriTemplate("/items/")
public class ItemsResource {
   @HttpContext
   private UriInfo context;
   
  
   public ItemsResource() {
   }

   public ItemsResource(UriInfo context) {
       this.context = context;
   }

   @HttpMethod("GET")
   @ProduceMime({"application/xml", "application/json"})
   public Collection<Item> get(@QueryParam("start")
   @DefaultValue("0")
   int start, @QueryParam("max")
   @DefaultValue("10")
   int max) {
         .......
   }

   @HttpMethod("POST")
   @ConsumeMime({"application/xml", "application/json"})
   public Response post(Item data) {
          .......
   }

   @UriTemplate("{itemId}/")
   public ItemResource getItemResource() {
       return new ItemResource(context);
   }
}


Resource com.iona.resources.ItemResource :

//ItemResource.java
public class ItemResource {
   
   private UriInfo context;

	/** Creates a new instance of ItemResource */
   public ItemResource() {
    }

   public ItemResource(UriInfo context) {
       this.context = context;
   }
 
   @HttpMethod("GET")
   @ProduceMime({"application/xml", "application/json"})
   public Item get(@UriParam("itemId")Integer ItemId) {

         .......
   }
   
   @HttpMethod("PUT")
   @ConsumeMime({"application/xml", "application/json"})
   public void put(@UriParam("ItemId")
   Integer id, Item data) {

         .......
   }

   @HttpMethod("DELETE")
   public void delete(@UriParam("ItemId")
   Integer id) {

         .......
   }
  
   @UriTemplate("orders/")
   public OrdersResource getOrdersResource(@UriParam("itemId")
   Integer id) {
                 final Item parent = getEntity(id);
       return new OrdersResource(context) {
           protected Collection<Order> getEntities(int start, int max){
           	Set<Order> entities = parent.getOrderTableCollection();
               if (entities == null) { 
               }
               return entities;
           }
       };
   }

}

There also should be some EntityProvider generated for converting ProduceMime and ConsumeMime types to Java object?

Starting from importing and creating some POJO classes

Users also can create a empty rest project, and then import some POJO java object, add REST annotations in the class using STP Resource View.

Resource View

In this view, a selected project is the input of the view, all java classes which annotated with REST annotation will be displayed as resource node in left tree viewer.

Users could do following operations on the Resource view:

* Open resource by double clicking on the any node of the tree, the corresponding Java file will be open with Java file editor
* Add new resource be selecting a Java class, then available methods of the class will be list in under the resource node.
* Edit resource by change annotations in the attribute editor, once a annotation is changed, it will be saved as annotation in Java file , 
different nodes have different annotation types.

Update Resource annotation:

Res.JPG

Update Method annotation:

Method.JPG

Update Parameter annotaion:

Param.JPG

Deploy REST Project

  • Standalone Mode: Need to create server mainline file.
  • container mode: Need to add jpa lib to containers's classpath or packaged in the war file

REST Test Framework

Goals

Short Term Goal

User can easily setup the test data of a rest service, run the test case and see the response data from server.

Medium Term Goal

User can add some assertions to a test case and all the test cases can be run automatically. The test report also will be generated for user.

Long Term Goal

We need a generic service test framework that supports the testing for different kinds of services (e.g. jaxws service, restful service).




Design for Short Term Goal

UI Design

Ui-1.0.JPG

In the RestServiceTestCaseView, user can do the following operations:

1. Add/remove a rest project to be tested.  And system will search the resouces of the project automatically. 
2. Add/remove/start/stop a test case.
3. Refresh this tree view. System will search resources in all the projects listed in the view and update the view.
4. System will save the tree viewer as an xml file in the local file system. If the user restart IDE or re-open this view, the xml file will be used to initialize this tree viewer.

In the RestServiceTestCaseEditor, user can set up the test data in configuration section and the response data will also be displayed in the response section after running this test case. And all the data will be saved to the local file system. If the user restart the IDE, these data will re-display in the two sections.

[Note] Please refer to section "Data Model" below for more information.


Class Diagram

Classdiagram-1.0.JPG


Data Model

Datamodel-1.0.JPG

The data model is used to save/load test case informations.


Next Step

TBD :)