kintoneのGoライブラリを触ってみる


# はじめに

[kintone Advent Calendar 2015](http://qiita.com/advent-calendar/2015/kintone) 20 日目の記事です。

最近 Go 言語を触り始めて、kintone 関連でも何かやってみたいなと思っていたところ、kintone のコマンドラインツールの実装にも使われている、[kintone/go-kintone](https://github.com/kintone/go-kintone) というリポジトリを発見したので早速触ってみようと思います。

# go-kintone でできること

一通りの CRUD 処理はできるようです。

* レコードの取得（GET）
* レコードの登録（POST）
* レコードの更新（PUT）
* レコード削除（DELETE）

それから添付ファイル関連も操作できるようです。

* ファイルダウンロード
* ファイルアップロード

あと便利なのがこれです。

* フィールド一覧の取得 (フォーム設計情報の取得)

ここまでできてしまえば、コマンドラインツールやエージェントを作るなど十分にできそうです。
それでは早速触ってみようと思います。

まずは

```
% go get github.com/kintone/go-kintone
```

してから、import 文に、`"github.com/kintone/go-kintone"` を追加しておきます。


# クライアントの初期化

REST API を呼び出す起点になるクライアントを初期化します。

```
app := &kintone.App {
	Domain: <Domain>,
	User: <user>,
	Password: <Password>,
	AppId: <AppId>,
}
```

App という構造体を構造体リテラルを使って初期化しています。
App はアプリ ID していることから明確ですが、特定のアプリを指しています。

App 構造体には、Timeout フィールドや ApiToken フィールドがあるので、必要に応じて設定します。

# App から呼び出せる REST API

メソッドとの対応は以下の様になっていて、表にしてみたものの特に迷うところはないです。

| Method / Path | メソッド |
|:----------|:------------|
| GET /k/v1/record.json | GetRecord() |
| GET /k/v1/records.json | GetRecords() |
| POST /k/v1/record.json | AddRecord() |
| POST /k/v1/records.json | AddRecords() |
| PUT /k/v1/record.json | UpdateRecord() |
| PUT /k/v1/records.json | UpdateRecords() |
| DELETE /k/v1/records.json | DeleteRecords() |
| GET /k/v1/file.json | Download() |
| POST /k/v1/file.json | Upload() |
| GET /k/v1/form.json | Fields() |

# 実際に呼び出してみる

いくつかのメソッドを実際に呼び出してみます。

## レコードの一括取得

GetRecords メソッドを使います。

```
records, err := app.GetRecords(nil, "limit 10")
if (err != nil) {
	log.Fatal(err)
}

for _, record := range records {
	jsonArray, err := record.MarshalJSON()
	if (err != nil) {
		log.Fatal(err)
	}
	json := string(jsonArray)
	fmt.Println(json)
}
```

GetRecords の引数には、取得する kintone アプリのフィールドを渡します。
今回は全部ほしいので nil を渡します。
第二引数にはクエリとして文字列を渡します。

特定のフィールドの値を取り出したい場合は、レコード型の `Fields` フィールドにアクセスします。

```
record.Fields[<フィールドコード>]
```

`Fileds` フィールドは String 型を格納したマップで、フィールドコードを元に書くフィールドにアクセすることができます。

また、サブテーブルのフィールドにアクセスしたい場合は、型アサーションを使います。

```
record.Fields[<サブテーブルのフィールドコード>].(kintone.SubTableField)
```

SubTableField は Record 型のスライスなので、繰り返し処理でサブテーブルの中のフィールドにアクセスできます。

## レコードの一括登録

AddRecords メソッドを使います。
AddRecords の引数には、登録するデータとして Record 型のスライスを渡します。

Record を生成する手順は次のようになります。

1. 1 レコードつき、キーに string 型、要素にからインターフェースを持つようなマップを生成する。
2. マップに各フィールドの値を追加する。
3. kintone.NewRecored 関数にマップを渡して Record を生成する。

```
records := make([]*kintone.Record, 0)
	
record := make(map[string]interface{})
record[<フィールドコード>] = kintone.SingleLineTextField(<フィールドの値>)
records = append(records, kintone.NewRecord(record))
	
ids, err := app.AddRecords(records)
if (err != nil) {
	log.Fatal(err)
}

for _, id := range ids {
	fmt.Println(id)
}

```

最初に Record を格納して、最終的に AddRecords メソッドに渡すスライスを生成しています。
そのあと、先の手順にしたがって Record を生成します。
Record に追加していく各フィールドは、フィールドごとに対応する型を持っています。
上のコードでは「文字列（1行）」フィールドとして `SingleLineTextField` を使いましたが実際にはアプリに配置されているフィールドによって型を使い分ける必要があります。

# まとめ

go-kintone は非常に充実していてとても使いやすい印象でした。
kintone の API 自体は普通に HTTP クライアントを使えば呼び出すことはできるのですが、レコードデータの生成や、取得したデータを捌く処理を書くときに、go-kintone は非常に便利だと思いました。
Go ならではの分野として、go-kintone を使って軽量なエージェントを作ったり、SORACOM Beam と組み合わせて使えたら面白そうだと思いました。