Monday, 24 January 2011

Build your first grails application

Grails is an open source web application framework, that has been built with the aim to enable rapid application development (RAD). Grails uses groovy as it's primary programming language. It uses Convention over Configuration to speed up the process of web application development. Grails takes its inspiration from Ruby on Rails but for the java world. Grails runs on the JVM and brings the power of the scripting world since it uses groovy which is a dynamic language built on top of java. Read more about grails and it's features here.

In this article we will quickly build an application using Grails. You will be surprised to see that you have your web-app running within 15 minutes, save data to the database, even deploy you application on your favourite application server! Enough talking, let's get into action.
( find a download link for the source code of the sample plugin at the bottom of the page)



System Requirements

1. JDK 1.5 or above (for Grails 1.2 and above)
2. JAVA_HOME enviroment variable should be set, pointing to the correct jdk installation.
3. download and unzip the grails zip file into a folder of your choice.
4. create an environment variable GRAILS_HOME which points to the folder created in the step above.
5. Add GRAILS_HOME/bin and JAVA_HOME/bin to the PATH environment variable.

STEP 1: Create your web-application:

1. Open a command prompt at the location where you want to create your application.
2. Type the following command to create an application named 'estore'
 grails create-app estore

Change directory to your application:
 cd estore
We can see that the script creates the basic structure of the web-app, reducing the time and effort of the developers. Grails also downloads some plugins such as hibernate, tomcat etc. In case you face any issues you probably need to check your internet connection or setup you proxy.

Also, notice the environment (highlighted in the screenshot). The environment is set to 'development' mode.
Grails lets you configure your application for different environments, 'development' is the default environment. We will discuss these enviromnents in a short while.

The create-app command will create the following structure for you:

Grails application structure
As you see, grails has already done a lot of work for you! In fact, you already have a web application that you can try launching using the command 'grails app'. But as it is right now, the web-application would not be of much use.
Let's take a closer look at what grails has created for us. The folder with which you are going to work the most is 'grails-app'. Inside this folder, grails has created for us folders where we place our model (M-domain), views (V) and controllers. In addition to these, there's a folder for the service classes, taglibs, message property files (i18n) and configuration files.

Domain: This is where you'll place your domain classes (i.e. the models).
These are POJOs with some additional attributes such as 'mapping' which specifies the relationship the class holds with other domain objects, 'constraints' which specifies the constraints on the fields of the domain objects, etc. You don't need to provide getters and setters for all the fields.
Controller: This is where your controller classes will lie.Controllers handle requests and generate the response either themselves or delegate the request to a view. Every controller class name must end with 'Controller'. You can easily create a controller by creating a class who's name ends with 'Controller'. Or you could use the commands provided by grails which we will see in a moment.

Services: This is where you should place business logic. Every service class ends with 'Service'. You can create a service by simply creating a class who's name ends with 'Service' inside the service folder or you can use the commands provided by grails. To use this service in a controller or domain class you simply need to declare a variable named the same as your service, and the service will be automatically injected by spring at application startup. These services are by default singleton, i.e. the same instance of the service is used across the application. However, the scope of the service can be changed

Views: Views in grails are .gsp files which are very similar to jsp files. Controllers use 'convention mechanism' to delegate the request to the appropriate view. Grails uses SiteMesh for its layouts. Thus you can very easily specify the basic layout of your application in the grails-app/views/layout/main.gsp. You will see that you already have the main.gsp file generated for you when you create a fresh new application.


Taglibs: This is where you can add your custom tags but without the need to update any TLDs or any other configuration. Remember 'convention over configuration'. You can create a taglib by simply creating a class ending with 'TagLib' in the taglib folder or use the grails command which we will discuss just in a while.

Configuration Files: Although grails follows the 'Convention over configuration' paradigm, you need some basic configuration for your databases, working directory, logging, emails etc. All your configuration files would be placed inside 'conf'. There are a couple of configuration files but for now lets take a closer look at the important configuration files.

1. DataSource.groovy: As discussed earlier, grails allows you to configure your application for different environments using just a single file. Thus you don't need to maintain multiple copies of your property file per environment. You can place all your configuration inside one file, and you could even provide some common properties that remain unchanged across environments. Grails provides you with an in-memory HSQL database so you can quickly get started with your application and leave the task of choosing, installing and setting up a database for later. You can change the HSQL configuration to save data to a file, so you can see your test data in between application runs.
change the url to:
 url = "jdbc:hsqldb:file:testDb"
/* NOTE: For this tutorial, i have changed my applications url to the above, so that i don't have to re-generate my test data.  */

 2. Config.groovy: This is the config file where you can specify any application specific properties, environment specific log4j properties etc. The properties specified in this file can be read from any application code using ConfigurationHolder.
For example, the following property:
 email.notification=test@test.com
can be read using the following code:
  import org.codehaus.groovy.grails.commons.ConfigurationHolder
  ....
  ....
 sendNotification(ConfigurationHolder.config.email.notification, 'some test email')


3. BootStrap.groovy: This file has two methods, init & destroy, which are invoked on application startup and shutdown. So if you need to run some initialization code at startup or some clean up tasks at shutdown, this file is you will need.
Now that you are familiar with the structure of your grails application, let's move ahead ...

STEP 2: Create your first domain class

Let's create a domain class Product for our estore:
grails create-domain-class product
/*( NOTE: For the purpose of this tutorial, i am using the default package, i.e. i have removed any package structure, i.e. removed the 'package estore' line from the file and placed the Product.groovy file at grails-app/domain directly.)*/

Let's add some fields to the Product class so that it looks like this:
package com.estore

class Product {

    String name
    String description
    Double price

    static constraints = {
        description(nullable: true)
        name(blank: false)
        price(min:0D)
    }
}
As you can see here, we have added a few fields to the Product class and in addition also added some constraints. By default, all fields are Non-nullable. So here, we make description a nullable field, and also add a constraint to the minimum value of the price field.

STEP 3: Create a controller and views for the domain class

We would need some pages in our application to add/update/delete/list all the products in our store. There are two ways we can do this
1. Create a controller: Generate the controller and use scaffolding to generate the views at run-time.
Run the command:
grails create-controller com.estore.Product
Now open ProductController.groovy, and add the following code to it:
package com.estore

class ProductController {

    def scaffold = Product
}
Here, we are using the 'scaffolding' mechanism, where grails generates the views at run-time.  At this point, you are ready to run the application and test it using 'grails run-app'. But, i would suggest you first read the second way to do this before you try this one.
OR
2. Generate controller and views: Generate both the controller and the views on your disk.
Run the command:
grails generate-all com.estore.Product
Here, you will find that 4 files have been generated at grails-app\views\product namely create.gsp, list.gsp, edit.gsp and show.gsp. And the controller will have multiple 'actions'. These actions will be called depending on the URI that is requested.


Run the application using the command:
grails run-app
Browse to : http://localhost:8080/estore/product/create
(
Notice the URI:
   estore- application name
   product- controller name
  create- action name
)

You should be able to see something like this:

[ Try this: Try creating a product with a negative price value or a blank aname. Without writing a single line of code, you see your domain-class constraints being validated on the UI! That's grails for you :) ]
STEP 4: Adding relationships to your domain class

Let's enhance our store, and add categories to it. Products can belong to a certain category. And a category can have multiple products. So here we have a many-to-one relationship.
Create a new domain class called Category:
grails create-domain-class com.estore.Category
Add the following code to Category.groovy
package com.estore

class Category {

    String name
    String description
   
    static hasMany = [products: Product]
   
    static constraints = {
        name(blank:false)
        description(nullable:true)
    }
}
And add the following line to Product.groovy
Category category
static belongsTo = Category
Note: If you don't add this line to Product.groovy, the deletes would not be cascaded. We will not be getting into the details of how GORM works since it's out of the scope of this article.

Now create the views and controller for the Category domain class
grails generate-all com.estore.Category
Repeat the above command for com.estore.Product as well, since we've added a new field to the class, we need this to be reflected in the view.

 Run your app, you should see there are two controllers, and your product/create page looks like this:



 For better presentation, make a tiny change to grails-app/views/product/create.gsp ( and editp.gsp)
Change
 <g:select name="category.id" from="${com.estore.Category.list()}" optionKey="id" value="${productInstance?.category?.id}"  />

to

<g:select name="category.id" from="${com.estore.Category.list()}" optionKey="id" optionValue="name" value="${productInstance?.category?.id}"  />

STEP 5: Create a service class


You can create a service class by either creating a class ending with 'Service' in the services folder or  use the command:
grails create-service utility
To use this service in CategoryController.groovy just add this line to the file:

class CategoryController {

    def utilityService
     ....
 That's all you need to be able to use a service. You should add all your business logic to the service class and call it from the controller and domain classes.

So, that didn't take long now, did it ? ;)

Hope you find this article useful. Happy coding!

Download source code (estore.rar)

 

1 comment:

  1. Very useful article. Wish you best of luck .Keep writing articles it helps lot.

    ReplyDelete