【vte.cx入門】3.データをサーバに登録する：スキーマ定義編

vte.cxでは、自分で設計したデータを自由に登録し管理できます。

例えば、wikiアプリを作成し記事を投稿し、それをクラウド上で管理したり、社内の業務アプリを作成し、進捗状況等を記録管理したり、その使い方は多種多様です。プライベートなことや業務系のことまで、用途を問わずにvte.cxのデータ管理を活用することができます。

ここでは、その基礎となる**スキーマの定義**について説明します。

# スキーマとは
サーバに登録する**データの設計図**のようなものです。
基本的にスキーマ定義を見れば、どのデータがどのような形で管理されているのかがわかります。
また、[IndexやACL](http://reflexworks.jp/documentation.html#taggingservice.html#T4)などをサーバで管理するためにも必ずスキーマが必要になります。

# スキーマの形
スキーマはこのような形になっています。

```lang:スキーマ
userinfo
 id(int)
 email
favorite
 food!=^.{3}$
 music=^.{5}$
hobby{}
 type
 name
 updated(date)
```

これを設定しておくと、以下のようなJSONデータをサーバに登録できるようになります。

```
{
  userinfo: {
    id: 12345,
    email: hoge@foo.com
  },
  favorite: {
    food: 'りんご',
    music: 'J-POP'
  },
  hobby: [
    {
        type: '屋外',
        name: 'なわとび',
        updated: 2015/12/04
    },
    {
        type: '屋内',
        name: 'ゲーム',
        updated: 2015/09/01
    }
  ]
}
```

このように、スキーマでは親子関係(userinfoとidの関係)を設定したり、項目の型など設定することができます。
任意のデータをサーバに登録するためには、このようなスキーマを定義する必要があります。
スキーマを定義することで、どのデータをどういう形式で登録しているのかを管理できます。また、許可していない不正な形式のデータを登録するのを防ぎます。

つまり、**スキーマに定義していないデータは登録できず、スキーマに定義してあるデータのみ登録できるということです。**

では、このスキーマを設定する一連の流れと仕組みを説明したいと思います。

# 1. 登録したいデータを整理する（データモデル設計）
まず、スキーマの基本となるデータモデル設計を行ないます。
例えば、以下のようなデータを登録したいとします。

- ユーザの情報
 - id
 - メールアドレス
- お気に入り
 - 食べ物
 - 音楽
- 趣味
 - 種類
 - 名前
 - 更新日

これに英語名をつけます。
この英語名をスキーマでは使いますので、管理側が理解できる名前をつけてください。
項目名は**２文字以上１２８文字以下の英数字および一部の記号(_や$)が使えます。**
ただし、数字で始まるものやハイフンは使用不可です。

```
1hoge = ×
hoge1 = ◯
```

- ユーザの情報：**userinfo**
 - id：**id**
 - メールアドレス：**email**
- お気に入り：**favorite**
 - 食べ物：**food**
 - 音楽：**music**
- 趣味：**hobby**
 - 種類：**type**
 - 名前：**name**
 - 更新日：**updated**

次にデータの型情報を設定します。必須ではなく、必要な場合にのみ設定します。
今回は説明も兼ねて色々設定します。

- userinfo：**オブジェクト**
 - id：**数値**
 - email：**文字列**
- favorite：**オブジェクト**
 - food：**文字列**
 - music：**文字列**
- hobby：**配列**
 - type：**文字列**
 - name：**文字列**
 - updated：**日付**

「hobby」は必ずしも一つとは限らないので、配列型で管理したいと思います。
「userinfo」と「favorite」については、「id」や「food」の親階層になります。
配列で管理する必要もないので、オブジェクト型とします。

ここまでで、基本となるデータモデル設計は終了します。

# 2. データモデル設計を元にスキーマを作成する
前述したデータモデル設計を元にスキーマを組み立てると以下のようになります。

```lang:スキーマ
userinfo
 id(int)
 email
favorite
 food
 music
hobby{}
 type
 name
 updated(date)
```
## 親子関係
親（userinfo）の下に、子（id, email）を記述します。
この時、子の先頭には半角空白を入力します。
この形でデータの親子関係を表現します。

```
userinfo
{半角空白}id(int)
{半角空白}email
```

## 型の指定

型は基本的に「**（）(かっこ)**」の中に指定します。
数値型の場合は「**(int)**」と指定し、日付型の場合は「**(date)**」と指定します。文字列の場合は何も指定しません。

```
id(int) // 数値型
updated(date) // 日付型
```

配列にしたい場合は「（）(かっこ)」に指定するのではなく、「{}（中かっこ）」を指定します。

```
hobby{} // 配列型
```

オブジェクト型は**子階層がある場合は何も指定しません**。デフォルトでオブジェクト型になります。
**子階層がない場合、何も指定しないと文字列型となる**ため、注意してください。

```
favorite    ← オブジェクト型
 food       ← 子階層がある
hoge        ← 子階層が無いのに何も指定しないと文字列型
foo(int)
...
```

以下のような型情報を指定できます。

| 型 | 指定方法 | 例 |
|:-----------|:------------:|------------|
|数値型|(int)|hoge(int)|
|日付型|(date)|hoge(date)|
|Boolean型|(boolean)|hoge(boolean)|
|配列型|{}|hoge{}|

基本的なスキーマ定義はここまでです。

# 3. 必要に応じてバリデーションを定義する
スキーマにはバリデーションも設定することができます。
例えば「**食べ物情報は必須項目で必ず3文字でなければならない**」とか「**音楽情報は5文字でなければならない**」といった指定ができます。
それをふまえると以下のようなスキーマになります。

```lang:スキーマ
userinfo
 id(int)
 email
favorite
 food!=^.{3}$
 music=^.{5}$
hobby{}
 type
 name
 updated(date)
```

バリデーションは項目名に「**=**」を足し、それに続けて指定します。
必須項目は「**=**」の前に「!」を付けます。

```
food!    ← 必須項目
```


桁数は「hoge={最小桁数~最大桁数}」のように指定します。

```
food={2~5}    ← 2桁から5桁まで
```

配列の場合は{}の中に最大個数を指定します。

```
hobby{5}    ← 配列の長さは5個まで（例：['a', 'b', 'c', 'd', 'e']）
```

また、**バリデーションには正規表現**を指定できます。
例えば「**名前はアルファベット小文字のみ**」といった指定ができます。

```
name=[a-z]+{2~15}
```


# 4. スキーマをサーバに登録する
以上の工程を踏んでスキーマを準備できたら、いよいよサーバに登録します。
[cloneしたプロジェクト](http://qiita.com/takeyama/private/4ad7c3ac4f9e29694f37)の中にスキーマ定義ファイルがあるので、そこに記述します。
場所は以下です。

```
/setup/_settings/template
```

templateファイルをテキストエディタで開いたら以下のように記述します。

```lang:template
<feed>
  <entry>
    <link href="/_settings/template" rel="self"/>
    <contributor>
      <uri>urn:vte.cx:acl:/_group/$admin,CRUD</uri>
    </contributor>
    <contributor>
      <uri>urn:vte.cx:acl:+,R</uri>
    </contributor>
<content type="text/html">userinfo
 id(int)
 email
favorite
 food!=^.{3}$
 music=^.{5}$
hobby{}
 type
 name
 updated(date)
</content>
</entry>
</feed>
```
\<content>タグの中にスキーマを記述します。その他のタグは変更する必要はありません。
\<contributor>はACLの設定になります。ACLについては簡単に説明することができないので別途記事が上がります。
また、詳しくは[ACLの設定](http://reflexworks.jp/documentation.html#taggingservice.html#T4)を参照してください。

記述したら保存し、そのまま[デプロイ](http://qiita.com/takeyama/private/4ad7c3ac4f9e29694f37)してスキーマ定義完了です。


# デフォルトで登録されているスキーマ（予約語）
vte.cxでは[ATOM形式](http://reflexworks.jp/documentation.html#taggingservice.html#R2)を採用しています。
ですのでATOM標準タグが予約語になります。
具体的には以下のスキーマです。

| 項目名 | 意味 | 入力可否 | 補足 |
|:-----------:|:------------:|:------------:|:------------|
|author|作成者|×|サーバによって自動的にセットされます|
|id|識別id|×|同上|
|published|作成日|×|同上|
|updated|更新日|×|同上|
|title|タイトル|◯||
|subtitle|サブタイトル|◯||
|summary|概要|◯||
|content|コンテンツ格納用|◯|Content-Typeを指定できます。（HTMLやCSSやJSなど）|
|link|リンク情報|◯|別名(alias)や外部コンテンツのリンクとして使われます。|
|contributor|ACL情報|◯|ACL(権限)を管理するために使われます。|
|rights|暗号化情報|◯|暗号化される項目です。|

最悪スキーマ情報を登録しなくても、デフォルトのATOM標準項目だけでアプリ開発を行うこともできます。
上記項目はvte.cxを使用したアプリ製作の上で非常に大事なものなので、ぜひ覚えておいてください。

その他、詳細なスキーマの仕様は[こちら](http://reflexworks.jp/documentation.html#taggingservice.html#T)からご参照ください。

以上で、スキーマ定義について終わりたいと思います。

次はいよいよjQueryを使用し、実際にサーバへデータ登録を行っていきたいと思います。