Spring Bootで作ったRESTful APIをコンテナにして動かす

**親記事**
[クジラに乗って海に出た](http://qiita.com/gates1de/items/9231d9b501f4e16560ff)

# はじめに
さて1週間ぶりの投稿です.
前回は「DockerでWebサービスを作る」というところをメインにお話しましたが, 今回はそのサーバサイドであるSpring Bootで作ったRESTful APIについてのお話です.

最初に言っておきますが, Spring Bootについて全体的な知識を得たいのであれば[こちらの記事](http://qiita.com/opengl-8080/items/05d9490d6f0544e2351a)が非常にまとまっていてわかりやすいです.

ということで今回の対象者としては,

* Spring BootでRESTful APIをすぐにでも試してみたい人
* DBのテーブルでリレーションを組んだ時の実装を知りたい人
* Spring BootにおけるDBの初期化について知りたい人
* どうしてサーバサイドとフロントエンドが完全に切り分けられているのか知りたい人

などなど, ↑の記事の補足or載ってない感じのことを書いていこうと思います!

# ディレクトリ構成&ソースコード
```
.
├── Dockerfile
├── build (中略)
│   │
│   ├── dependency-cache
│   ├── libs
│   │   ├── myapp-0.0.1-SNAPSHOT.jar
│   │   └── myapp-0.0.1-SNAPSHOT.jar.original
│   ├── resources
│   │   └── main
│   │       ├── application.properties
│   │       └── db
│   │           ├── 00-database.sql
│   │           ├── data.sql
│   │           └── schema.sql
│   └── tmp(中略)
│      
|
├── build.gradle
├── build.sh
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── run.sh
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── myapp
    │   │               ├── MyApplication.java
    │   │               ├── config
    │   │               │   └── AppConfig.java
    │   │               ├── controller
    │   │               │   ├── AreaController.java
    │   │               │   ├── CityController.java
    │   │               │   ├── FoodController.java
    │   │               │   ├── GenreController.java
    │   │               │   ├── PrefectureController.java
    │   │               │   ├── RegionController.java
    │   │               │   └── RestaurantController.java
    │   │               └── domain
    │   │                   ├── model
    │   │                   │   ├── Area.java
    │   │                   │   ├── City.java
    │   │                   │   ├── Food.java
    │   │                   │   ├── Genre.java
    │   │                   │   ├── Prefecture.java
    │   │                   │   ├── Region.java
    │   │                   │   └── Restaurant.java
    │   │                   ├── repository
    │   │                   │   ├── AreaRepository.java
    │   │                   │   ├── CityRepository.java
    │   │                   │   ├── FoodRepository.java
    │   │                   │   ├── GenreRepository.java
    │   │                   │   ├── PrefectureRepository.java
    │   │                   │   ├── RegionRepository.java
    │   │                   │   └── RestaurantRepository.java
    │   │                   └── service
    │   │                       ├── AreaService.java
    │   │                       ├── CityService.java
    │   │                       ├── FoodService.java
    │   │                       ├── GenreService.java
    │   │                       ├── PrefectureService.java
    │   │                       ├── RegionService.java
    │   │                       └── RestaurantService.java
    │   └── resources
    │       ├── application.properties
    │       └── db
    │           ├── 00-database.sql
    │           ├── data.sql
    │           └── schema.sql
    └── test
        └── java
            └── com
                └── example
                    └── myapp
                        └── MyApplicationTests.java
```

`resources`, `controller`, `domain`あたりを中心に説明していきます.

ソースコードはこちら
https://github.com/gates1de/MyApp/tree/master/MyApp-server

# 実装
## Resources
`resources`は名前の通り, アプリのリソースを格納するディレクトリになります.
画像やcssといった静的ファイルはここに置くのが良いかと思われます.

そして`resources`には最初から`application.properties`が入っています.
ここにDBの設定を書いていきます.

``` src/main/resources/application.properties
# MySQL
spring.datasource.url=jdbc:mysql://mysql:3306/myapp_db?characterEncoding=UTF-8
spring.datasource.username=myapp
spring.datasource.password=password
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.initialize=true
spring.datasource.schema=classpath:/db/schema.sql
spring.datasource.data=classpath:/db/data.sql
spring.datasource.sqlScriptEncoding=UTF-8
```
DBに関する設定は基本的に`spring.datasource`の中に定義されているようです.

**1行目 : spring.datasource.url**
MySQLを外部においた場合のURLは`jdbc:mysql://<ホストネーム(IPアドレス)>:<ポート>/<DB名>`となります. ~~後半の`characterEncoding=UTF-8`はおまじないとして使ってます.~~
今回ホストネームが`mysql`となっているのは, Dockerを立ち上げる時の`docker-compose.yml`でリンクさせていたので, この名前(コンテナ名)にしておくだけで自動的に名前解決をおこなってくれるからなのです.

**2, 3行目 : spring.datasource.username, spring.datasource.password**
言うまでもないですがMySQLのユーザ名とパスワードです.
これを設定しておけば自動的に初期ユーザとして作成してくれるようです.

**4行目 : spring.datasource.driverClassName**
`JDBC(Java Database Connectivity)`はJavaからDBを操作するためのAPIですが, DBごとにドライバが必要になってきます. MySQLの場合`com.mysql.jdbc.Driver`, PostgreSQLの場合`org.postgresql.Driver`, といった感じです.
一覧がどこかにまとまっていないかな〜と思いましたが, なかったので使いたいDBの`driverClassName`は各自調べてみてください.

**5~7行目 : spring.datasource.initialize ,spring.datasource.schema, spring.datasource.data**
DBを初期化するかどうかの設定です.
これを`true`にしておくと, アプリのclasspath(つまり, `resources`ディレクトリまでのパス)直下から`data.sql`と`schema.sql`をアプリの起動時に読み込んでくれます.
ただ, `resources`ディレクトリ直下にファイルを置いておきたくなかったので, 自分は`db`ディレクトリの中に置くことにしました. この時に, 自分で`data`と`schema`を読みこませる方法として6, 7行目の設定を利用すれば良いのです. もちろんファイル名も`data.sql`と`schema.sql`にしなくてもこの設定さえしておけばどんな名前でも大丈夫です.

**8行目 : spring.datasource.sqlScriptEncoding**
Dockerの公式MySQLコンテナは日本語に対応してないこともあり, DBのUTF-8設定をちゃんとしておかないと文字化けします.
しかし, DBではちゃんと設定してあったのになぜか`data.sql`で日本語のデータをinsertすると文字化けするという現象がおきて少しハマりました.
それを解決するのがこの設定で, これも一応UTF-8に設定しておきましょう!

DBの初期設定はこれでおｋでしょう.
ちなみに, `schema.sql`はテーブル定義を書いておくファイルで, テーブルの`CREATE`文などを書きましょう.
`data.sql`には初期データの投入のために, `INSERT`文などを書きましょう.

## Controller
リクエストに対する処理とレスポンスをこの`controller`でおこないます.
一つピックアップして説明しましょう.

``` java:src/main/java/com/example/myapp/controller/CityController.java

package com.example.myapp.controller;

import java.lang.Iterable;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.example.myapp.domain.model.City;
import com.example.myapp.domain.model.Restaurant;
import com.example.myapp.domain.model.Food;
import com.example.myapp.domain.service.CityService;
import com.example.myapp.domain.service.RestaurantService;
import com.example.myapp.domain.service.FoodService;

@RestController // ・・・ 1
@RequestMapping("/api/v1/cities") // ・・・ 2
public class CityController {

    @Autowired
    CityService cityService;

    @Autowired
    RestaurantService restaurantService;

    @Autowired
    FoodService foodService;

    @RequestMapping(method = RequestMethod.GET) // ・・・ 3
		public List<City> getCities() {
			return cityService.findAll();
		}

    @RequestMapping(value = "{id}", method = RequestMethod.GET) // ・・・ 4
		public City getCity(@PathVariable Integer id) {
			return cityService.findOne(id);
		}

    @RequestMapping(value = "{id}/foods", method = RequestMethod.GET) // ・・・ 5
		public List<Food> getFoods(@PathVariable Integer id) {
			return foodService.findByCity(id);
		}

    @RequestMapping(value = "{id}/restaurants", method = RequestMethod.GET) // ・・・ 6
		public List<Restaurant> getRestaurants(@PathVariable Integer id) {
			return restaurantService.findByCity(id);
		}
}
```

この`Citycontroller`というのは, 主に日本の市町村に関するデータを返すAPIとして動作します.
ちょっとこの辺り命名規則も`service`の使い方も合ってるのかまだ不明ですが, とりあえず動作の説明をしてみます.

**1の説明**
`@RestController`アノテーションをつけると, 戻り値を`ResponseBody`のコンテンツとして返してくれる. つまるところ, HTMLのbodyとして返してくれるという認識であってそう. ([この記事](http://qiita.com/tag1216/items/3680b92cf96eb5a170f0)が非常でわかりやすく説明してくれてます. )
確かに[ドキュメント](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestController.html)みてもそんな感じのことが書いてますね.

**2の説明**
`@RequestMapping`は見ただけでも分かると思いますが, いわゆるルーティングの指定です.
ここでの意味は`http://hogehoge/api/v1/cities`にアクセスしたら`CityController`の処理に入るという感じです.

**3の説明**
ここから本質のところです. 今度の`@RequestMapping`は上記のルートに`GET`でアクセスしたら, `getCities()`に入る, という感じです.
`service`については後ほど説明しますが, `findAll()`と書かれているのを見て, どんなレスポンスになるか分かるかと思います. `cities`テーブルから全データ取得してJSON形式で返します.
なぜJSONで返されるのかというと, `@RestController`が`ResponseBody`のコンテンツを返すという話をしましたが, 返り値として`List<>`を返すと自動的にJSONにして返してくれるようです.

**4の説明**
ここでの`@RequestMapping`は, `value`と`method`が設定されています. `value`は↑で述べたのと同様に, ルートのことです. このルーティングは, `http://hogehoge/api/v1/cities/:id`にアクセスしてなおかつ`GET`リクエストの場合, `getCity()`に入る, という感じです.
`findOne`ということはご察しの通り, 該当する`id`の市町村を1件返すという処理ですね.

**5と6の説明**
そして今度は市町村じゃないデータが紛れ込んでいる処理ですね.
これは`cities`に紐づく`foods`を取得する処理になります(ご当地グルメとか名物とかだと思って頂ければ).
`http://hogehoge/api/v1/cities/:id/foods`に`GET`でアクセスすると, 該当する市町村のグルメを全件取得する, といった処理になります.
6も同様に, 該当する市町村の飲食店を全件取得する処理です(よくグルメサイトとかで, 都道府県から地域や市町村選択してから店の一覧が出てくるみたいなのありますよね).

時間がなくて`GET`だけのAPIになってしまい残念ですが, なんとなく実装できそうな気がしますよね! 是非`POST`や`PUT`, `DELETE`なども使ってやってみてください!

## Model
一番ハマったポイントがこの部分のコーディングです.
また一つ例を取り上げてみます.

``` java:src/main/java/com/example/myapp/domain/model/City.java
package com.example.myapp.domain.model;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Column;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.ManyToMany;
import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;

import javax.validation.constraints.NotNull;

import com.example.myapp.domain.model.Area;
import com.example.myapp.domain.model.Restaurant;
import com.example.myapp.domain.model.Food;

import com.fasterxml.jackson.annotation.JsonIgnore;


@Entity
@Table (name = "cities")
public class City implements Serializable {
	
	@Id
	@NotNull
	@GeneratedValue (strategy = GenerationType.IDENTITY)
	@Column (name = "id", nullable = false)
	private int id;

	@NotNull
	@Column (name = "name", nullable = false)
	private String name;
	
	@NotNull
	@Column (name = "code", nullable = false)
	private String code;

	@NotNull
	@Column (name = "area_code", nullable = false)
	private String areaCode;

	@Temporal (TemporalType.TIMESTAMP)
	@Column (name = "created_at")
	private Date createdAt;

	@Temporal (TemporalType.TIMESTAMP)
	@Column (name = "updated_at")
	private Date updatedAt;


	@ManyToOne (cascade = CascadeType.ALL, fetch = FetchType.EAGER) // ・・・ 1
	@JoinColumn (nullable = false, insertable = false, updatable = false, name = "area_id") // ・・・ 2
	private Area area;

	@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "city") // ・・・ 3
	private List<Restaurant> restaurants;

	@ManyToMany (mappedBy = "cities")
	private List<Food> foods;


	public int getId() {
		return this.id;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return this.name;
	}
	
	public void setCode(String code) {
		this.code = code;
	}

	public String getCode() {
		return this.code;
	}
	
	public void setAreaCode(String areaCode) {
		this.areaCode = areaCode;
	}

	public String getAreaCode() {
		return this.areaCode;
	}
	
	public Date getCreatedAt() {
		return this.createdAt;
	}
	
	public void setUpdatedAt(Date updatedAt) {
		this.updatedAt = updatedAt;
	}

	public Date getUpdatedAt() {
		return this.updatedAt;
	}
	

	@JsonIgnore // ・・・ 4
	public Area getArea() {
		return this.area;
	}

	@JsonIgnore
	public List<Restaurant> getRestaurants() {
		return this.restaurants;
	}

	@JsonIgnore
	public List<Food> getFoods() {
		return this.foods;
	}
}
```

全部説明するのはこれまたネットの情報としては冗長的なので, 説明しませんが[こちらの記事](http://qiita.com/ughirose/items/5d691adc677aa08636b8)を見ると良いかもしれません(公開時期的にタイムリーですね!笑)

**1の説明**
`@ManyToOne`は多対1の関連があるカラムを表すためのアノテーションになります.
ここでは`Area`というEntity(Class)が対象となっていますが, これは数カ所の市町村をひとまとめにした「地域」を表すEntityのことを指しています.
例えば, 「東銀座」は「銀座・有楽町・新橋・築地・月島」という地域に属している, という感じです.
「東銀座」は他の地域に属することはなく, 1地域にしか属しません. そして他に, 「汐留」も「銀座・有楽町・新橋・築地・月島」という地域に属します.
よって1つの地域は多くの市町村を持ち, 各市町村は1地域にしか属さない, ということで多対1になり`@ManyToOne`を付与する形となったわけです.

また, `cascade = CascadeType.ALL`についてですが, `cascade`は`MySQL`にもありますが, 親テーブルが更新された時には子テーブルも更新されるという設定になります. `ALL`を指定したので`PERSIST, MERGE, REMOVE, REFRESH, DETACH`が可能になるようです(まだ学習中なので説明できず...[こちらをどうぞ](http://juzow.hatenablog.com/entry/20121017/1350480972)).

`fetch = FetchType.EAGER`に関しては, 親となるデータを取り出した時にこのデータも一緒に取り出すというのが要約になります. ↑の例で言えば, 「銀座・有楽町・新橋・築地・月島」という地域を取得した時に, 一緒に「銀座」, 「汐留」, ...を取り出すということです.
`FetchType.LAZY`だと, 親となるデータを取り出しても, 子のデータを参照しなければ取り出さない, 遅延参照になります.

**2の説明**
`@JoinColumn`はその名の通り, テーブル結合を表すアノテーションです.
`name = "area_id"`を指定することで, `cities`テーブルの`area_id`カラムをもとにjoinすることができます.
`nullable = false, insertable = false, updatable = false`はそのままの意味ですが, null・データの追加・データの更新は許容しないことを意味します. つまりは, 読み取り専用のカラムとして定義されるはずです(地域や市町村のデータは基本的に書き換えないのでそうしてます).

**3の説明**
`@OneToMany`もその名の通り, 1対多の関連を表すアノテーションです.
`mappedBy = "city"`なんてのがありますが, これは`Restaurant`Entity(クラス)の対象プロパティを指します.
ソースコードを見てもらえるとわかると思いますが, `Restaurant`クラスには`@ManyToOne`がついたフィールドがあり, それが`city`という名前になっているはずです.
こんな感じでリレーションを実現していきます.

**4の説明**
`@JsonIgnore`はちょっと特殊なのですが, `Jackson`というJSONパーサライブラリを導入することで利用可能にあるアノテーションです(例のごとく[こちら](http://qiita.com/opengl-8080/items/b613b9b3bc5d796c840c)をどうぞ).
例えば, `controller`の説明の時`findAll()`とかありましたけど, これが呼び出された時, 全ての地域と各地域に紐づく市町村を全て取得するようになっています.
となると, 市町村のデータは親である地域の情報も同時に取得されます(`City`クラスは`Area`フィールドを持っているかつ`@JoinColumn`で結合していて, `getArea()`も用意されているため).
するとまた, 地域に紐付いた市町村データ全て取得する...という風に**循環参照**してしまうのです.

これを避けるために`@JsonIgnore`アノテーションを付与することで`getArea()`はJSONに含めないようにすることができます.
`getArea()`を使いたいときは直接呼び出すのがいいと思います, 多分.
これはちょっとハマったので覚えておいて憂いなしです.

## Repository
`repository`はDBから情報を取得・更新などをおこなう役割を担っています.
また1つピックアップして説明します.

``` java:src/main/java/com/example/myapp/domain/repository/FoodRepository.java
package com.example.myapp.domain.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.example.myapp.domain.model.Food;
import com.example.myapp.domain.model.City;


public interface FoodRepository extends JpaRepository<Food, Integer> {

	@Query (value = "select * from foods f inner join foods_cities fc on f.id = fc.food_id where fc.city_id = :cityId and f.is_specialty = true", nativeQuery = true)
	List<Food> findByCity(@Param("cityId") Integer cityId);

}
```

まず, `JpaRepository`を継承していることがみてとれますが, こうすることで`findAll()`や`save()`など基本的なDB操作のためのメソッドが使えるようになります(ドキュメントは[こちら](http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html)).
`JPA(Java Persistence API)`は, O/RマッパーとしてJavaのアプリケーションにおけるDB操作を楽にしてくれます. `Ruby on Rails`では`ActiveRecord`が有名ですね.

そして, `@Query`の`value`を見てみると, 普通のSQLクエリが書いてありますね.
`@Query`内のSQLクエリは`findByCity(cityId)`というメソッドにて発行できる, といった感じです.
ちなみに, `nativeQuery = true`にしておかないと, `select * from ...`の`*`とかが使えません.

## Service
最後に, `service`についてです.
役割としては, `repository`を通じてDBに処理要求をし, 結果を返却するという感じです.
以下例を示します.

``` java:src/main/java/com/example/myapp/domain/service/FoodService.java
package com.example.myapp.domain.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.myapp.domain.model.Food;
import com.example.myapp.domain.repository.FoodRepository;


@Service
@Transactional
public class FoodService {
	@Autowired
	FoodRepository foodRepository;

	// 料理全件取得
	public List<Food> findAll() {
		return foodRepository.findAll();
	}

	// 料理1件取得
	public Food findOne(Integer id) {
		return foodRepository.findOne(id);
	}

	// 市区町村のidに紐づく料理を全て取得
	public List<Food> findByCity(Integer cityId) {
		return foodRepository.findByCity(cityId);
	}
}
```

もう説明もいらないくらいシンプルな例になってしまって申し訳ないですが, 例えば最後の`findByCity(cityId)`について説明すると, `FoodRepository`で`findByCity(cityID)`にあたるSQLクエリを書いたので, それを`FoodService`内で呼び出して, DBへ処理要求を出します.
あとは処理結果をそのまま返却するだけにしています.
DBから取得した値をゴニョゴニョ加工したい場合にはここでやるのもいいかと思います.

そして`controller`でも説明したとおり, `controller`内部で`service`を`@Autowired`でインジェクション(インスタンスの手動生成が不要)して, APIにアクセスがあった時に適宜DBから該当するデータ取得し, 結果を返却するという役割を担うわけです.

基本的な使い方に関しては以上になります.

## Build
最後にbuild方法をさらっと.
自分は`Gradle`でbuildをおこなうことにしましたので, `build.gradle`にbuildの設定を書きます.

``` gradle:build.gradle
buildscript {
  ext {
    springBootVersion = '1.3.5.RELEASE'
  }
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  }
}

apply plugin: 'java' // ・・・ 1
apply plugin: 'spring-boot'

jar {
  baseName = 'myapp' // ・・・ 2
  version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
  mavenCentral()
}

configurations {
  providedRuntime
}

dependencies {
  compile('org.springframework.boot:spring-boot-starter-data-jpa')
  compile('org.springframework.boot:spring-boot-starter-redis')
  compile('org.springframework.boot:spring-boot-devtools')
  compile('org.springframework.boot:spring-boot-starter-web')

  compile('com.fasterxml.jackson.core:jackson-core:2.7.4')
  compile('com.fasterxml.jackson.core:jackson-databind:2.7.4')
  compile('com.fasterxml.jackson.core:jackson-annotations:2.7.4')

  runtime('mysql:mysql-connector-java')

  providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')

  testCompile('org.springframework.boot:spring-boot-starter-test')
}
```

buildのコマンドは基本的に
`$ build gradle`
ですが, 今回は最初からテストにコケてしまっているので, 以下のコマンドでbuildします.
`$ build gradle -x test`
また, コンテナを作成したかったら
`$ docker build -t コンテナ名 .`
を実行してください.
(もちろん`$ docker-machine start VM名`でVMを起動, `eval $(docker-machine env VM名)`をやってから)


今回は`java`コマンドで動く`jar`ファイルを作成したかったので, 上記のコードにある
`apply plugin: 'java' `(**1**と書かれた部分)
を入れておくことで, `./build/libs`の中に`jar`ファイルが作成されるようになります.
上記のコード**2**と書かれた部分がアプリケーションの名前とバージョンになりますが, これが`jar`ファイルの名前になります. フォーマットは`<baseName>-<version>.jar`となります. 今回の例で言うと, `myapp-0.0.1-SNAPSHOT.jar`が生成されるはずです.

# おわりに
本当はCRUDを実装しようとしましたが間に合わず...
今後の様子を見てやってみようかと思います.

とりあえず, Docker + Spring Bootでサーバサイドを構築するのはそんなに難しいことではないので, 開発環境としてでも作ってみるのがいいと思います!

そしてフロントエンドと切り分けた理由としては, 自分がメインでiOSアプリを開発していたのと, 今時のフロントエンドを学びたかったという背景があり, iOSアプリとWebアプリのどちらも開発に取り組めるようにしたかったことにあります.
WebアプリをSpring Bootで全部作ってしまうと, iOS側の実装にAPIを別で作るのも手間だったのでそういうふうにしました.
とにかく, Web APIはモバイルエンジニアでも作成できたほうが開発の幅が広がって楽しくなると思います.

ということで, 不明な点がありましたらコメントお待ちしております!
それではまた〜!

---
<Font color="lightgray">p.s. 意識がアレだったので, 文章になってなさそうなところあったら教えて下さいｗ</font>