In the recent several days I was working on a Grails web application which provides a REST API implementation.
1 | # My environment information |
Basic
Scaffolding
Like Rails, you can create the project structure by executing some commands easily. In my case I used the following ones:
1 | grails create-app apidoc --profile=rest-api |
Note that based on the “profile“ concept in Grails, I can just generate the files for REST API instead of the files needed for an ordinary HTML view web application. This is done by using the “grails create-app apidoc –profile=rest-api” command above.
Now a running web application is ready although no logic is added yet.
Database
Grails use “H2” database by default. If you want to switch to such as MySQL, you can refer here.
Before deploying your Grails application to production environment, you need to generate DDL script and create the database/tables in your RDBMS such as MySQL. Refer here to view how to do it. Run commands like below:
1 | # By default the "development" environment is used. |
Package & Deployment
There are several ways to deploy a Grails application. Refer here to get the details.
In my case, I choose the “runnable war” manner:
1 | # Package for specific environment. The war file is generated in "build/libs/". |
Problems
Time format
In the JSON output of the Grials REST API, by default the “java.util.Date” type will be rendered into the string format like “2017-01-22T17:23:17Z”. It took me a lot of time to figure out how to customize this time string into some other format like “2017-01-22 17:23:17+0800”.
First, the following solution does not work for me:
1 | http://stackoverflow.com/questions/690370/how-to-return-specific-date-format-as-json-in-grails |
Finally I figure out the following solution by myself:
Update the “apidoc/grails-app/views/**/*.json” files to customize the JSON output, for me the files are:
1 | apidoc/grails-app/views/feature/_feature.gson |
Note that the “*.gson” files are also valid Groovy script:
1 | /* |
1 | import com.jd.xdata.apidoc.Feature |
Standalone war running exception
For the first time I run the Grails web application in the “standalone war“ mode, I got the following exception:
1 | Caused by: java.io.FileNotFoundException: JAR entry !/META-INF/services/org.hibernate.boot.registry.selector.StrategyRegistrationProvider not found in C:\Users\frank\AppData\Local\Temp\jar_cache3915609090913132890.tmp |
The solution is here: add the following content at the end of the “build.gradle” file:
1 | ext { |
MySQL Chinese encoding error
The problem need a 2-part solution:
- In the MySQL server side
1 | -- From: |
- In the Grails application side
1 | # In the "grails-app/conf/application.yml" file, update the database "datasource" info: |
Grails logging
To add logging feature to your Grails application, you need to update the “grails-app/conf/logback.groovy” file in your project:
1 | // Configure the rolling file appender for the production environment logging. |
The most important point of the “logback.groovy” configuration is the following sentence from here:
Most appenders require properties to be set and sub-components to be injected to function properly. Properties are set using the ‘=’ operator (assignment). Sub-components are injected by invoking a method named after the property and passing that method the class to instantiate as an argument. This convention can be applied recursively to configure properties as well as sub-components of any appender sub-component. This approach is at the heart of logback.groovy scripts and is probably the only convention that needs learning.
Another point is that, in your Grails controller code, a variable named “log” is avalaible without the need of declaration, which means you can use it to write logging lines directly.