-
Notifications
You must be signed in to change notification settings - Fork 48
Getting Started
This page helps you getting started with the JSR 311 plugin for Grails. It is assumed that you have a basic understanding of Grails and JSR 311 (JAX-RS: The Java API for RESTful Web Services). The examples in the following chapters have been tested to work with Grails 1.3.1 but should also work with Grails 1.2.x. For instructions how to download and install Grails refer to the Grails reference documentation section 2.1. The Using Eclipse section on this page explains how to setup the examples in Eclipse.
To use the plugin we create a new Grails project. Change the working directory to a location where you want to create a new Grails project and enter
grails create-app hello
on the command line. This creates a new directory hello
The following methods will download the latest released version of the plugin from the Grails Plugin Repository. For further installation options, such as installing a development snapshot, refer to the Installation Instructions.
Add the plugin dependency declaration to the project's BuildConfig.groovy
($PROJECT_DIR/grails-app/conf/BuildConfig.groovy
)
grails.project.dependency.resolution = {
plugins {
compile ':jaxrs:0.8'
}
}
And in the created hello
directory enter
grails refresh-dependencies
Go to the created hello
directory and enter
grails install-plugin jaxrs 0.7
To create a JAX-RS resource named test
enter
grails create-resource test
This will create a TestResource.groovy
file under grails-app/resources
and a TestResourceTests.groovy
file under test/unit
. The TestResourceTests.groovy
file is a unit test template. The TestResource.groovy
file is the generated JAX-RS resource. Both files are in the hello
package.
package hello
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
@Path('/api/test')
class TestResource {
@GET
@Produces('text/plain')
String getTestRepresentation() {
'Test'
}
}
It defines a single method that responds to HTTP GET operations. The HTTP response contains the return value of this method, Test
in this example. The content type of the response (Content-Type
header) is text/plain
. The created resource is ready to use as shown in the next section.
Creating resources via the command line is only one option. An alternative is to create resource files by hand. Any *Resource.groovy
file created under grails-app/resources
is assumed to be a JAX-RS resource and auto-detected by the grails-jaxrs plugin. These resources are checked for the presence of JAX-RS annotations as defined by JAX-RS 1.1 specification, section 3.1. Resources that aren't properly annotated are ignored by the plugin.
To start the application enter
grails run-app
on the comamnd line. Then open a browser window and go to http://localhost:8080/hello/api/test
. The browser should now display "Test
".
The grails-jaxrs plugin also support code changes at runtime i.e. without restarting the server. To demonstrate that we let add a name
parameter to the getTestRepresentation
method and bind it to a name
query parameter using the JAX-RS @QueryParam
annotation. The HTTP response entity will vary depending on the name
query parameter. Here's the modified source code.
package hello
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
@Path('/api/test')
class TestResource {
@GET
@Produces('text/plain')
String getTestRepresentation(@QueryParam('name') String name) {
"Hello ${name ? name : 'unknown'}"
}
}
When you save the changes the plugin re-initializes the JAX-RS runtime. Go to http://localhost:8080/hello/api/test?name=Martin
and you should see Hello Martin
in the browser window. If you additionally want to factor out the greeting logic into a Grails service, refer to the [service injection](Advanced Features#service-injection) section for instructions.
Available in version 0.4 or higher. A WADL document for resources managed by the plugin can be generated by sending a GET request to http://localhost:8080/hello/application.wadl
. The result should look like
<application xmlns="http://research.sun.com/wadl/2006/10">
<doc xmlns:jersey="http://jersey.dev.java.net/" jersey:generatedBy="Jersey: 1.1.4.1 11/24/2009 01:30 AM"/>
<resources base="http://localhost:8080/hello/">
<resource path="/api/test">
<method name="GET" id="getTestRepresentation">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string" style="query" name="name"/>
</request>
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
</resources>
</application>
Generating WADL documents only works when the plugin is [configured](Advanced Features#jax-rs-implementation) to use Jersey as JAX-RS implementation.
The grails-jaxrs plugin also supports scaffolding. It allows you to generate a RESTful service interface for one or more domain classes based on JAX-RS resource classes. Supported representation formats are XML and JSON. The following sections walk through a simple example. Please note that the scaffolding feature of the plugin is still early-access.
To create a Person
domain class go to the project's root directory and enter
grails create-domain-class person
Open the generated Person.groovy
file (under grails-app/domain
) and add two properties, firstName
and lastName
.
package hello
class Person {
static constraints = {
}
String firstName
String lastName
}
To generate JAX-RS resources that implement the RESTful service interface for that domain class enter
grails generate-resources hello.Person
This will generate two resource classes, PersonCollectionResource.groovy
and PersonResource.groovy
(in the hello
package) that support HTTP POST, GET, PUT and DELETE operations for creating, reading, updating and deleting Person
objects, respectively. PersonCollectionResource.groovy
is related to Person
lists, PersonResource.groovy
is related to individual Person
instances. Let's take a look at how to use the generated RESTful service interface.
Start the hello
application with
grails run-app
New person objects can be created by POSTing to http://localhost:8080/hello/api/person
. The following request POSTs an XML representation of a person object.
POST /hello/api/person HTTP/1.1
Content-Type: application/xml
Accept: application/xml
Host: localhost:8080
Content-Length: 82
<person>
<firstName>Sam</firstName>
<lastName>Hill</lastName>
</person>
The Content-Type
header must be set either to application/xml
. After sending the request, the server creates a new person object in the database and returns an XML representation of it.
HTTP/1.1 201 Created
Content-Type: application/xml
Location: http://localhost:8080/hello/api/person/1
Transfer-Encoding: chunked
Server: Jetty(6.1.14)
<?xml version="1.0" encoding="UTF-8"?>
<person id="1">
<firstName>Sam</firstName>
<lastName>Hill</lastName>
</person>
The client explicitly requested an XML representation via the Accept
request header. Note that the returned representation differs from the submitted representation by an id
attribute in the <person>
element. This id is also contained in the Location
response header, the URL of the created resource. The response code is 201
(CREATED
). Let's create another person object using a JSON representation. Here's the request
POST /hello/api/person HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: localhost:8080
Content-Length: 58
{"class":"Person","firstName":"Fabien","lastName":"Barel"}
The response also contains a JSON representation of the created person (see Accept
request header). The id of the created person object is 2
.
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:8080/hello/api/person/2
Transfer-Encoding: chunked
Server: Jetty(6.1.14)
{"class":"Person","id":"2","firstName":"Fabien","lastName":"Barel"}
Content negotiation via Content-Type
and Accept
headers works for other HTTP methods as well. To GET a list of created persons, open a browser (Firefox in our example) and enter the URL http://localhost:8080/hello/api/person
. This returns an XML representation of the list of persons stored in the database.
An XML representation is returned because Firefox sets an Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
request header. To get the representation of a single person, specify the id in the URL. For example, to get the person with id 1 use http://localhost:8080/hello/api/person/1
If you try to get a person that doesn't exist, an error message (with a status code 404
) is returned.
In the next step we update the first name of person 1 by PUTting a new representation to http://localhost:8080/hello/api/person/1
.
PUT /hello/api/person/1 HTTP/1.1
Content-Type: application/xml
Accept: application/xml
Host: localhost:8080
Content-Length: 85
<person>
<firstName>Samuel</firstName>
<lastName>Hill</lastName>
</person>
The response is a new representation of the updated person.
HTTP/1.1 200 OK
Content-Type: application/xml
Transfer-Encoding: chunked
Server: Jetty(6.1.14)
<?xml version="1.0" encoding="UTF-8"?>
<person id="1">
<firstName>Samuel</firstName>
<lastName>Hill</lastName>
</person>
GETting the person list again shows the update of person 1.
Finally, we delete person 1 by sending a DELETE request to http://localhost:8080/hello/api/person/1
.
DELETE /hello/api/person/1 HTTP/1.1
Accept: application/xml
Host: localhost:8080
GETting the person lists again shows that person 1 has actually been deleted.
The using GORM section of the Advanced Features page walks through the source code of the generated JAX-RS resources.
Prerequisites: Eclipse 3.5.x or higher and an installation of the SpringSource Tool Suite (STS).
Using the hello
project with the grails-jaxrs plugin in Eclipse requires a bit more than just importing the hello
project. After import, the grails-jaxrs classes are not on the classpath of the project, therefore, you'll see compile errors for generated JAX-RS resources. The best way to resolve the compile errors is to import the grails-jaxrs plugin project as a separate project in Eclipse and reference that project from the hello
project.
To checkout a released version of the grails-jaxrs project enter
git clone git://github.com/krasserm/grails-jaxrs.git
on the command line. This will create a local repository grails-jaxrs
, which is the root directory of the project. Then switch the repository to a tagged version or leave the master branch if you want to use the latest development version.
To import the project into Eclipse go to File -> Import... -> General -> Existing Projects Into Workspace
and press Next
. Then select the project's root directory and click Finish
. You should now see a jaxrs
project in the package explorer.
To add this new project as dependency to the hello
project, right-click on the hello
project and go to Properties -> Java Build Path -> Projects -> Add...
. Select the jaxrs
project from the list of projects in the workspace and press OK
. The compile erros should now disappear.
- Take a look at the Advanced Features of the grails-jaxrs plugin.