Grails

**Grails** （**グレイルズ**）は、プログラミング言語 Groovy を使用するオープンソースのWebアプリケーションフレームワーク。Grails や Groovy はJavaプラットフォーム上で動作する。「設定より規約 (convention over configuration)」というパラダイムにより高い生産性を実現し、スタンドアロンの開発環境を提供しつつ、開発者からはその設定の詳細を隠蔽している。

かつては "Groovy on Rails" と名乗っていたが、Ruby on Rails の David Heinemeier Hansson の要求で現在の名称になった。開発は2005年7月に開始され、2006年3月29日に 0.1 をリリース、2008年2月18日に 1.0 をリリース、2011年12月15日に 2.0、2015年3月31日に 3.0 をリリースした。

## 概要
Grails は以下のような目標を掲げて開発されてきた。

* Javaプラットフォームの高生産性のWebフレームワークとする。
* Hibernate や Spring Framework といった既に広く使われているJavaテクノロジーを単純で一貫したインタフェースで再利用する。
* 一貫性があり習得が容易なフレームワークとする。
* フレームワークを構成する各部分についてユーザーに分かりやすい文書を提供する。
* 複雑で一貫性のない分野でユーザーが期待するものを提供する。
** 強力で一貫した永続性フレームワーク
** GSP (Groovy Server Pages) を使った強力で使いやすいビューテンプレート
** Webページコンポーネントを簡単に作成できるダイナミックタグライブラリ
** 容易に拡張/カスタマイズ可能なAjaxサポート
* フレームワークの威力を示すためのサンプルアプリケーションを提供する。
* Webサーバや自動リソース再ロード機能など、完全な開発環境を提供する。

Grails は習得しやすく、アプリケーション開発と拡張が容易となるよう設計された。一貫性と強力な機能との正しいバランスを保つことを心がけている。

## 高い生産性
Grails は従来のJavaによるWeb開発フレームワークに比べて生産性を高めるため、以下の3つの特徴を備えている。

* XMLコンフィギュレーション不要
* 即座に使える開発環境
* Mixin経由の機能

### XMLコンフィギュレーション不要

JavaによるWebアプリケーション作成では、開発開始時点や途中で環境やフレームワークの構成設定が必要である。そのコンフィギュレーションは XML ファイルとして切り出して設定しやすくし、構成設定をアプリケーションのコードに埋め込まないようにすることが多い。

XML によるコンフィギュレーションはアプリケーション間の一貫性を高めるということで当初は歓迎された。しかし最近では、有効性は認めるものの、実際にXMLファイルの設定を修正するのは面倒だという人が多くなっている。アプリケーションが成長するにつれて、開発者はフレームワークのコンフィギュレーションを理解し、維持することに時間を費やすことになり、生産性を低下させる要因になっている。アプリケーションに機能を追加したり修正したりする度にXMLコンフィギュレーションも修正していると、アプリケーションの改良が遅くなり、生産性が低下する。

Grails では、XMLコンフィギュレーションファイルの修正を不要にした。その代わり、フレームワークが規約を使ってアプリケーションのコードを調べる。例えば、grails-app/controllers フォルダ内の名前の最後が `Controller` となっているクラス（例えば `BookController`）は、MVCのコントローラと見なされる。対応するビューも無指定の場合は grails-app/views/コントローラ名/アクション名.gsp となる。

ただし、設定が全くないわけではなく、データベースやログの設定などは `ConfigSlurper` の形式で grails-app/conf フォルダ内に配置する。ここの設定は `GrailsApplication.config` から読み込める。

### 即座に使える開発環境
従来のJavaによるWebツールキットでは、開発環境の整備は開発者が行わなければいけなかった。Grails は完全な開発環境を備えており、Webサーバ（Apache Tomcat）やデータベース（H2 Database）なども含んでいて、即座に使用することができる。全ての必要なライブラリはディストリビューションに含まれており、JavaのWeb環境も自動的に用意する。

`grails run-app` で内蔵サーバーを起動できるが、この場合は、開発モードになり、ソースコードの変更は自動的にリロードされ、適用される。開発モードの場合、初期設定は、H2 Database のオンメモリデータベースとなっている。本番環境向けは、`grails war` で war ファイルにまとめ、Apache Tomcat などに配備することができる。

### Mixin 経由の機能
Grails はいくつかのクラス上で Mixin 経由の動的メソッドを用意している。Grails では Mixin はメソッドである。Mixin はクラスに動的に追加される機能であり、あたかもその機能がプログラム上でコンパイルされたかのように利用できる。

この動的メソッドは、クラスを拡張したりインタフェースを実装したりすることなく、操作を実行できるようにする。Grails では、クラスの種類に基づいて動的メソッドを提供する。例えば、ドメインクラスはセーブ/削除/検索などの永続性操作を自動化するメソッドを持っている。

## Web フレームワーク
Grails は、MVCパラダイムにしたがって設計されている。ここでは、コントローラとビューについて解説する。モデル(ドメインクラス)については後述する。

Grails のアプリケーションは、以下のような `grails` コマンドによって作成される。
 grails create-app myapp
このコマンドによって、`myapp` ディレクトリ配下にGrailsアプリケーションに必要なディレクトリ構造やライブラリ等の雛形が生成される。

### コントローラ
Grails はWebページの振る舞いを実装するのにコントローラを使う。以下のコードはコントローラの例である。

```groovy
class BookController {
    def list() {
       [ books: Book.findAll() ]
    }
 }
```

1つのコントローラは複数のアクションを持ち、上のコントローラには list アクションがあり、データベース内の全ての本を含むモデルを返す。戻り値として 連想配列内で books を返しているが、これはビューから参照できる。上記例はビューのファイル名が無指定なので、grails-app/views/book/list.gsp になる。

このコントローラを生成するには、`grails create-controller book` コマンドを使う。`grails-app/controllers` ディレクトリにクラスが作成される。コントローラクラスは作成するだけで Grails に認識される。list アクションは  にマッピングされる。

コントローラで XML や JSON などを返したいときは以下のように行える。

```groovy
import grails.converters.*
 class BookController {
    def json() {
       render Book.list() as JSON
    }
 }
```


### ビュー
Grails は GSP (Groovy Server Pages) と JSP をサポートしている。基本的には GSP を使用する。以下のコード例は GSP で書かれたビューであり、上記のコントローラが用意したモデル内の本のリストを表示する。


```xml
<!doctype html>
<html>
  <head>
    <title>Our books</title>
  </head>
  <body>
    <ul>
      <g:each in="${books}">
        <li>${it.title} (${it.author.name})</li>
      </g:each>
    </ul>
  </body>
</html>
```


デフォルトのファイル名の命名規則は `grails-app/views/コントローラ名/アクション名.gsp` であり、このビューはGrailsプロジェクトの `grails-app/views/book/list.gsp` として保存する。この位置に保存することで `BookController` と `list` アクションにマッピングされる。また、この位置に置くだけで Grails がこれをビューとして認識する。

GSP では `${}` の部分で変数やメソッドを利用できる。標準設定はエスケープされずにそのまま出力されるが、grails-app/conf/Config.groovy の grails.views.default.codec を html にすると、HTMLエスケープして出力される。

### Ajax サポート
Grails は、バージョン 2.0 以降、標準で jQuery サポートを取り込んでいる。また、プラグイン等で OpenRico、Prototype、Yahoo! UI libraryといった Ajax ライブラリをサポートしている。AjaxコードとHTMLを生成する既存のタグライブラリを利用できる。また、自前のタグライブラリを生成するのも容易である。

### ダイナミックタグライブラリ(タグリブ)
Grails は各種タグライブラリを提供するが、同時に自前のタグライブラリ(タグリブ)を簡単に作成できる。

```groovy
class ApplicationTagLib {
  def formatDate = { attrs, body ->
    out << new java.text.SimpleDateFormat(attrs.format).format(attrs.date)
  }
}
```
この `formatDate` タグライブラリは  オブジェクトを  にフォーマットする。このタグライブラリは `grails-app/taglib/ApplicationTagLib.groovy` ファイルに追加するか、ファイル名の末尾を `TagLib.groovy` として `grails-app/taglib` ディレクトリに置く。

以下は、GSP で `formatDate` タグライブラリを使ったコード断片である。


```
<g:formatDate format="yyyyMMdd" date="${myDate}"/>
```
 

ダイナミックタグライブラリを GSP で使う場合、インポートタグを使う必要がない。ダイナミックタグライブラリはJSPファイルでも使えるが、GSPよりも若干作業が多い。

## 永続性

### モデル(ドメインクラス)
Grailsで扱うデータ(モデル)は、GORM (Grails Object Relational Mapping) と呼ばれるORマッピング機構を使ってデータベースに格納される。ドメインクラスは、以下のような `grails` コマンドを使って作成し、`grails-app/domain` ディレクトリ配下に配置する。

 grails create-domain-class myapp.Book

すると、ドメインクラス名を聞かれるので入力すると、適当なファイルが作成される。以下に `Book` クラスのコードを示す。

```groovy
class Book {
    String title
    Person author
 }
```

上のドメインクラスは、書籍名を`String`型の `title`、著者を `Person`型の `author` として持つデータモデルを定義している。

GORMの機能によって、Grailsアプリケーション実行時にこのドメインクラスに対応するテーブル `book` がDB上に作成され、このテーブルは数値型の `id`、数値型の`version`、 文字列型の `title`、 `person`テーブルの`id`への外部キーである `author_id` の4つのカラムを持つ。Grailsアプリケーション開発者は、SQLをほとんど意識せず、ドメインクラスのメソッドとしてこれらのデータへのアクセスを記述することができる(もちろん、必要に応じてGORMのバックエンドであるHibernateが処理可能なHQLの形式でクエリを発行することもできる)。

このように、ドメインクラスを作成するだけで、Grails によって永続化されたデータを管理できる。ドメインクラスに主キーのための`id`とバージョン管理のための`version`が明示的に宣言されていない場合にもそれらを付加する機能は、Grails 0.3 以降の GORM で提供されている。

### Scaffold
Grailsは、ドメインクラスからコントローラやビューを自動生成する機能も提供している。これはScaffoldと呼ばれる機能で、静的Scaffoldと動的Scaffoldの2種類のScaffoldが提供されている。

静的Scaffoldを行うには、ドメインクラス `Book` を作成した後に以下のようなコマンドを使う。
 grails generate-all myapp.Book
このコマンドによって、基本的な CRUD (Create, Read, Update, Delete) 操作をすべて行うことができる雛形が生成される。コントローラ `BookController` や、4つのビュー `list.gsp`、 `create.gsp`、 `edit.gsp`、 `show.gsp` などである。このScaffoldによって、Grailsアプリケーション開発者は、ドメインクラスを記述するだけで基本的なCRUD操作が可能なWebアプリケーションの雛形を得ることができる。

また、コントローラに以下のように記述することで、任意のドメインクラスを動的Scaffoldすることができる。

```groovy
class BookController {
    static scaffold = true
 }
```

動的Scaffoldは、静的Scaffoldのようなファイル生成を行わず、CRUD 操作を `` 上で提供する。

### メソッド
GORMで管理されるドメインクラスには、クラスおよびオブジェクト上で永続性操作を行う動的メソッドと静的メソッドがある。

#### 動的インスタンスメソッド
`save()` メソッドはオブジェクトをデータベースにセーブする。

```groovy
def book = new Book(title:"The Da Vinci Code", author:Author.findByName("Dan Brown"))
 book.save()
```

`delete()` メソッドはオブジェクトをデータベースから削除する。

```groovy
def book = Book.findByTitle("The Da Vinci Code")
 book.delete()
```

`refresh()` メソッドはオブジェクトの状態をデータベースに基づいて更新する。

```groovy
def book = Book.findByTitle("The Da Vinci Code")
 book.refresh()
```

`ident()` メソッドはデータベースからそのオブジェクトに割り当てられたIDを取り出す。

```groovy
def book = Book.findByTitle("The Da Vinci Code")
 def id = book.ident()
```


#### 動的静的（クラス）メソッド
`count()` メソッドは、指定されたクラスについて、データベース上のレコード数を返す。

```groovy
def bookCount = Book.count()
```

`exists()` メソッドは、指定されたIDのオブジェクトがデータベース上に存在するかどうかをブーリアンで返す。

```groovy
def bookExists = Book.exists(1)
```

`find()` メソッドは、指定されたオブジェクトクエリ文でデータベースから見つかった最初のオブジェクトを返す。

```groovy
def book = Book.find("from Book b where b.title = ?", [ 'The Da Vinci Code' ])
```

この場合のクエリ構文は Hibernate HQL である。

`findAll()` メソッドは、データベースに存在する全オブジェクトを返す。

```groovy
def books = Book.findAll()
```

`findAll()` メソッドは、クエリ文を指定し、それにマッチした全オブジェクトのリストを返す。

```groovy
def books = Book.findAll("from Book")
```

`findBy*()` メソッドは、指定したパターンにマッチした最初のオブジェクトを返す。

```groovy
def book = Book.findByTitle("The Da Vinci Code")
```

または:

```groovy
def book = Book.findByTitleLike("%Da Vinci%")
```

`findAllBy*()` メソッドは、指定したパターンにマッチした全オブジェクトのリストを返す。

```groovy
def books = Book.findAllByTitleLike("The%")
```

`findWhere*()` メソッドは、一連のパラメータにマッチした最初のオブジェクトを返す。

```groovy
def book = Book.findWhere(title:"The Da Vinci Code")
```


### 古いデータベースモデル
GORMの永続性機構は Hibernate を使って実装されている。そのため、古いデータベースであっても標準の Hibernate mapping ファイルを使ってGORMクラスにマッピングできる。

## Javaプラットフォームとの連携
Grails はJavaプラットフォーム上に構築されているため、Javaライブラリ、フレームワーク、既存コードベースとの連携が容易である。特に Hibernate ORMフレームワークとはクラスの透過的連携を実現している。したがって、Hibernate を使った既存アプリケーションを再コンパイルや再設定することなく、上述の動的永続性メソッドを使ってGrailsを使うことができる。

その結果、Hibernate にマッピングされたJavaクラスのために scaffolding を設定できる。また、Grails Webフレームワークの機能は全て、これらのクラスとそれを使うアプリケーションに使用可能である。

## 脚注

## 関連項目
* JRuby
* Jython

## 外部リンク
* 
* Grailsフレームワーク - リファレンスドキュメント 英語版
* Groovy 公式サイト
* 日本 Grails/Groovy ユーザーグループ
** Grails Japan!
** Grailsフレームワーク - リファレンスドキュメント 日本語訳版
* Getting Started with Grails, by Jason Rudolph, InfoQ Enterprise Development シリーズという本の1つ - ユーザー登録するとPDFをダウンロード可能