NetBeansとJavaEEを用いて、ポケモンの日本語名、英語名、ドイツ語名、フランス語名、韓国語名を返すRESTfulなAPIを開発してみようという記事の実装編です。
“NetBeansとJavaEEで、ポケモンの日英仏独韓の名前を返すRESTなAPIを開発してみた - 準備編 -”の続きです。
APIの流れ
作成したクラス群
前回の準備編で用意したクラスは以下の4つでした。
パッケージ / クラス名 | 用途 |
---|---|
.pkmn.api PkmnBaseApi.java |
API本体のクラス。リクエストを受け取り、適切なLogicを呼び出し、値を返却する。 |
.pkmn.logic PkmnBaseLogic.java |
データの処理を行うクラス。APIからの呼び出しで、必要に応じてDAOを呼び出す。 |
.pkmn.dao PkmnBaseDao.java |
DB操作を行うクラス。Logicからの呼び出しでDBの値を取得・更新・削除する。 |
.pkmn.entity PkmnBaseEntity.java |
データ管理用のクラス。DBのレコードに対応している。 |
用途の欄にも記載してある通り、ブラウザからのリクエストを受けるのはAPI本体となるPkmnBaseApi.javaです。その後の流れは以下の通り。
基本的にはデータベースのレコードと対応した Entityクラスを箱として、DAOがデータを取得し、それをLogicがAPIに返す(必要ならここで何らかの処理をする?)みたいな流れです。
実装
用意したデータベース(pkmn_db)
pkmn_dbは以下のようなテーブル(pkmn_base)を持っています。中には図鑑番号をKeyとし、日本語名、英語名、ドイツ語名、フランス語名、韓国語名を格納できるようになっています。
mysql> show tables;
+--------------------+
| Tables_in__pkmn_db |
+--------------------+
| pkmn_base |
+--------------------+
1 row in set (0.03 sec)
mysql> desc pkmn_base;
+------------------+-------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------+------+-----+-------------------+-------+
| number | int(5) | NO | PRI | NULL | |
| jp_name | varchar(10) | NO | | NULL | |
| en_name | varchar(10) | YES | | NULL | |
| ge_name | varchar(10) | YES | | NULL | |
| fr_name | varchar(10) | YES | | NULL | |
| kr_name | varchar(10) | YES | | NULL | |
| created_datetime | datetime | NO | | CURRENT_TIMESTAMP | |
| updated_datetime | datetime | NO | | CURRENT_TIMESTAMP | |
+------------------+-------------+------+-----+-------------------+-------+
8 rows in set (0.02 sec)
データを格納するEntityクラスを実装
上記ののテーブル構造に合わせた、Entity(PkmnBaseEntity.java)クラスを実装します。Fieldごとの変数を用意し、それぞれのセッター/ゲッターを作成します。
なお、@Entityや@Tableなどのアノテーションを付与すると、ちょいちょい警告が出ますが、その際は適切なimport(NetBeansが推薦してくれます)を追加していく必要があります。
PkmnBaseEntity.java
@Entity
@Table(name="PKMN_BASE")
public class PkmnBaseEntity implements Serializable {
@Id
private Integer number;
private String jp_name;
(中略)
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getJp_name() {
return jp_name;
}
public void setJp_name(String jp_name) {
this.jp_name = jp_name;
}
(以下略)
クライアントからのリクエストを受けるAPIクラスを実装
今回は、標準的なメソッドであるGETを使って、すべてのデータを取得するgetAllと、図鑑番号を指定して一体のみのデータを取得するgetを実装します。
PkmnBaseApi.java
値はJSON形式で返すので、returnはString型ですが、JSON.encode()としています。また、getメソッドにはnumberのパラメータが必要なので、QueryParamで渡します。
@Path("/pkmn")
public class PkmnBaseApi {
@EJB
private PkmnBaseLogic pkmnBaseLogic;
@GET
@Path("get")
public String get(@QueryParam("number") Integer number) {
PkmnBaseEntity pke = pkmnBaseLogic.get(number);
return JSON.encode(pke);
}
@GET
@Path("getAll")
public String getAll() {
List<PkmnBaseEntity> pkeList = pkmnBaseLogic.getAll();
return JSON.encode(pkeList);
}
}
ちなみに、各メソッド内で、PkmnBaseLogicクラスを使っているので、それを次に実装します。引数のデータ型や個数を間違えないよう注意。(間違ってたらNetBeansが指摘してくれるけど)
APIからの呼び出しで、実質的な処理を行うLogicクラスを実装
PkmnBaseLogic.java
APIからgetを呼ばれるか、getAllを呼ばれるかで挙動が異なります。
@Stateless
public class PkmnBaseLogic {
@EJB
private PkmnBaseDao pkmnBaseDao;
public PkmnBaseEntity get(Integer number){
return pkmnBaseDao.find(number);
}
public List<PkmnBaseEntity> getAll(){
return pkmnBaseDao.getAll();
}
}
いずれのメソッドもPkmnBaseDaoクラスを使っているので次はそれを実装します。
Logicからの呼び出しで、DBとのやり取りを行うDAOクラスを実装
PkmnBaseDao.java
entityManagerというものを使って、データベースへの検索を行います。
@Stateless
public class PkmnBaseDao {
@PersistenceContext
private EntityManager entityManager;
//number指定検索
public PkmnBaseEntity find(Integer number){
return entityManager.find(PkmnBaseEntity.class, number);
}
//全てのデータを取得
public List<PkmnBaseEntity> getAll(){
CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(PkmnBaseEntity.class));
return entityManager.createQuery(cq).getResultList();
}
}
データベースへの接続やクエリの発行についてはEntityManagerが請け負っている、という認識ですが、接続設定については人間の手で入れなければなりません。
それに関しては次回のDB設定・接続編で扱いたいと思います。