We’re now set up with a running Grails system. We’ve created a sample ‘test’ application, and we’re now going to walk through some of cool Grails functionality. Oops! We forgot two minor steps before we go any further. Start an application server and … well, that’s just the one step we forgot.
Starting the webserver
In the PHP world, we’re pretty used to using Apache in most scenarios. PHP and Apache have gone together like peanut butter and jelly for the better part of a decade. Moving over in to the Java world will take a little getting used to. Why? For starters, you have many choices for servers to run your application. Sure PHP can run under IIS, lighthttpd and other servers, but it’s fair to say that 95% of PHP projects run under Apache. In the Java world you have your choice of Tomcat, Jetty, Glassfish, JBoss and numerous others. How should you choose?
Don’t.
At least, don’t try to decide right now. Each of those servers offers a number of differentiating factors that will take time to learn. To start with, you can use Jetty. And you can use it without having to do anything at all, because it’s bundled with Grails. Nice, eh? From the root directory that was created by your ‘create-app’ command earlier, just tell grails that you want to run your app:
cd /home/michael/tmp/test
grails run-app
You’ll see something like this:
Welcome to Grails 1.0-final-SNAPSHOT – http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /apps/downloads/grails
Base Directory: /home/michael/tmp/test
Environment set to development
Note: No plugin scripts found
Running script /apps/downloads/grails/scripts/RunApp.groovy
Running Grails application..
2008-01-29 22:48:50.698::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
2008-01-29 22:48:51.326::INFO: jetty-6.1.4
2008-01-29 22:48:51.133::INFO: No Transaction manager found – if your webapp requires one, please configure one.
2008-01-29 22:48:54.920:/test:INFO: Set web app root system property: ‘test’ = [/home/michael/tmp/test/web-app/]
2008-01-29 22:48:54.926:/test:INFO: Initializing Log4J from [/home/michael/tmp/test/web-app/WEB-INF/classes/log4j.properties]
2008-01-29 22:48:54.052:/test:INFO: Initializing Spring root WebApplicationContext
[0] spring.GrailsWebApplicationContext Refreshing org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@768dc8: display name [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@768dc8]; startup date [Tue Jan 29 22:49:00 EST 2008]; parent: org.springframework.web.context.support.XmlWebApplicationContext@850e8c
[1] spring.GrailsWebApplicationContext Bean factory for application context [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@768dc8]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1c98c1b
2008-01-29 22:49:04.592:/test:INFO: Initializing Spring FrameworkServlet ‘grails’
2008-01-29 22:49:04.794::INFO: Started SelectChannelConnector@0.0.0.0:8080
Server running. Browse to http://localhost:8080/test
Yeah, that’s again a whole lot of information that generally you will just ignore, at least to start with. What you need to concern yourself with is that last line – Grails is telling you where to point your browser to see the fruits of your labor. Browse to localhost:8080 and have a look.
Creating a domain class
I mentioned before that Grails has conventions – rules that, if followed, will result in certain things happening. One main convention is the concept of domain classes. Any class that is created in the ‘domains’ directory will have persistence methods automatically available to it (save, load, etc.). And Grails gives you a command to create domain classes pretty quickly.
michael@localhost:~/tmp/test$ grails create-domain-class artist
Welcome to Grails 1.0-final-SNAPSHOT – http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /apps/downloads/grails
Base Directory: /home/michael/tmp/test
Environment set to development
Note: No plugin scripts found
Running script /apps/downloads/grails/scripts/CreateDomainClass.groovy
[copy] Copying 1 file to /home/michael/tmp/test/grails-app/domain
Created for Artist
[copy] Copying 1 file to /home/michael/tmp/test/test/integration
Created Tests for Artist
Yeah, I’m gonna walk through a cheesy artist/album/song example in the next few installments (at least, that’s the plan right now!). So be thinking along those lines.
So we have an ‘artist’ class in the grails-app/domain directory. If we open it up (grails-app/domain/Artist.groovy) we see:
class Artist {
}
Not much there yet, right? Let’s add a few things that we’d like to know about the artist.
class Artist {
String name
String debutYear
String hometown
}
Bear with me, I know this is very slapdash design. I’m going to demonstrate just a bit more Grails magic, then we can discuss what’s going on in more detail.
In the Grails world, we generally interact with the user via controllers – code that controls the business logic, uses domains for data management, and views for displaying the results. Let’s create ourselves a controller, again using the built-in Grails commands.
grails create-controller artist
Welcome to Grails 1.0-final-SNAPSHOT – http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /apps/downloads/grails
Base Directory: /home/michael/tmp/test
Environment set to development
Note: No plugin scripts found
Running script /apps/downloads/grails/scripts/CreateController.groovy
[copy] Copying 1 file to /home/michael/tmp/test/grails-app/controllers
Created Controller for Artist
[mkdir] Created dir: /home/michael/tmp/test/grails-app/views/artist
[copy] Copying 1 file to /home/michael/tmp/test/test/integration
Created ControllerTests for Artist
So we’ve got a controller now. Let’s reload our home page:
Whoah! An ‘artistController’ link! The default grails home page will dynamically create a list of all the controllers in the controllers directory. When we create a new one, the default page will show up in the list. But if we click the link…
class ArtistController {
def index = { }
}
This is all we have created for us – an ‘index’ method on the controller with nothing in it. However, as we saw in the error above, there’s no ‘view’ file. So we get an error. Now, we could tell Grails to generate a view file for us, but there’s a faster way to get things moving: scaffolding. The term popularized by Rails auto-generates CRUD screens for automatically. We can have Grails works this magic for us by changing one line in the controller file:
class ArtistController {
// def index = { }
def scaffold = Artist
}
Well, that was 2 lines – but you get the picture. Or not – maybe you need to see the picture. Make that change, then reclick the artistController link on your home page. You should see this:
I’ll leave it to you to play around with the CRUD stuff there – you don’t need screenshots of all that right now to get the idea.
grails – the unJava
Now, to the untrained eye, all this seemed relatively painless. We just created some files, reloaded the browser pages and “Bob’s your uncle” (I really do have an uncle named Bob!) the changes are there! So simple and straightforward from the PHP perspective, but wholly unnnatural for most of the Java world. If you’ve ever tried Java before and got fed up with recompiling and redeploying war files to your app server, Grails should make you think twice about web development with Java. Grails is recompiling any changed file on-demand, saving you a lot of hassle you’d normally have to deal with with ‘plain old’ Java. It’s not perfect – there are still times when I save/reload and ‘beat’ Grails, and it gives me an error because the file is in flux. This is pretty rare, though, and is not a deal breaker for me. Much of Java development has been a deal breaker over the years, compared to PHP and other ‘save/reload’ platforms, which is why I’m so excited about Grails these days.
The other interesting thing you’ll notice about the scaffolded demo we put together here is that it’s functional which just the few lines of code we put up. Play with the controller – go on! You can add/edit/delete artist information, yet we didn’t set up any database information. Just like Grails comes with a default application server (Jetty), it comes with a default database (HSQL), and is configured to use an in-memory setup. This is great for ‘get up and go’ testing, as you’ve already seen.
Lastly, as you may have noticed, we simply created a ‘domain’ class, and data can be managed. Grails is domain-driven: the framework works around the domain definitions you create, and will generate SQL and other persistence stuff for you based on that. Many other frameworks, including in the PHP world, work the opposite way. You create database tables which are then reverse-engineered and classes generated based on that information. Certainly not all frameworks are that way but it’s not the norm in the PHP world. It’s not necessarily better or worse than a db-driven approach, but certainly feels comfortable after a while. You *can* use pre-existing schemas, and you can influence the schema generation definitions with extra code in the domain classes – we’ll talk about those in an upcoming article.
I think I’ve given you more than enough to work through for now. Let me know your feedback and check back in the next few days for the next installament!




Very nice reading.
Just a quick note, the Symfony framework has also all this king of stuff, called “admin generator”: http://www.symfony-project.org/book/1_0/14-Generators#Administration
Keep up the good work!
Hell Niko:
Thanks for the feedback. The biggest difference I see is that in symfony one needs to have a separate ‘schema’ file to generate stuff (forms, database tables). I know you can generate the schema from the database, but in either case, you need that separation from the core code. Grails derives db schema and form generation from the domain class itself.
I haven’t used symfony enough to know this – can symfony generate a class from the schema.yml file? Or directly from the database?
Thanks again Niko!
Yes it can, it’s one of its main feature
In practice, you define your model in a schema.yml in this format:
propel:
blog_post:
_attributes: {phpName: BlogPost}
id:
title: varchar(255)
body: longvarchar
created_at:
And your run the propel-build-model command, and then it will generate for you all ORM classes to handle data in the table you’ve just created.
Then you can run the command propel-init-admin for this new model and you’ll have all admin forms to web manage your data (CRUD)
Give it a try, it’s neat and efficient
Oops, indentation of the schema has been lost after posting… Sorry for that.
So you can generate the schema.yml from the database, then generate a class from that. 2 step process, right? I have to say I’ve never been a huge propel fan. Symfony makes it arguably easier, I will admit. Last I used it – last October – I was surprised how easy it was to get started. After the initial setup, however, I found symfony still far too complex for my needs. At the time I didn’t have the few days I thought it would need to get comfortable. with it to be productive.
This is the odd thing – for me Grails felt like I was more productive off the bat, however, I can’t say for sure I was. I may have just been more excited about it, because it wasn’t “yet another php framework”.
True, Symfony is a bit complex at first look, but it’s also one of the most serious and featureful framework in the PHP world (the latter, I agree, has not plenty of seriously made stuff). Symfony’s very professional and make the use of PHP by far less “dirty”.
The learning curve is low at first (say, exponential) because you got a lot of conventions and architectural concepts to learn and understand to be really efficient, but when you’ve done this little work, you’re really, really productive because you simply have never to reinvent the wheel.
And you’re right, every PHP developer should at least learn another programming language
I like your explanation. I tried many of the PHP frameworks an the best seemed to be CAKE. I tried Rails also.
I think Grails is the best! I am not a java programmer
Just wanted to point out that “def scaffold” should be “static scaffold”. If you use def, the newer versions of grails will get confused and think that scaffold is an action. You’ll get a weird ClassCast Exception.