ARX CHALLENGERS BLOG技術者ブログ
ARX CHALLENGERS BLOG技術者ブログ
2024/04/09
こんにちは。嫌なことはすぐ忘れて、都合のいいことだけ覚えられるようになりました。hidedxです。
だいぶ、期間が空いてしまいました。第1、2回目で無事環境構築できましたので、実践編ということで
簡単なサンプルを作成していきたいと思います。
※第1回 https://www.airex.co.jp/arxblog2/uncategorized/20230915/
※第2回 https://www.airex.co.jp/arxblog2/uncategorized/20231003/
Apache Wicketを利用して、REST APIを作成してみましょう。
REST APIとは、2000年にRoy Fielding氏が提唱した、分散システムにおいて複数のソフトウェアを連携させるのに適した設計原則の集合。また、狭義には、それをWebに適用したソフトウェアの設計様式のこと。
出典:https://e-words.jp/w/REST.html
詳しいことはググってもらって、先に進みたいと思います(笑)
では、まず簡単なところで、以下のようなAPIを作成していたいと思います。
1. ユーザからリクエストされる。リクエスト方法はHTTPリクエスト(HTTPメソッドはGET)
2. APIはリクエストを受けて、JSONデータを返却する
ちなみに上記の図はPlantUMLを利用して作成しました。
興味がある方は利用してみてください。
では、REST APIの実装を進めていきましょう。WicketでREST APIを実現するためには、wicketstuff-restannotationsが必要です。詳しくは以下を参考に進めていきます。
https://github.com/wicketstuff/core/tree/master/wicketstuff-restannotations-parent
① xmlに記載追記
pom.xmlに以下を追記します。versionは利用環境に合わせてください。
<dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>wicketstuff-restannotations</artifactId>
<version>9.13.0</version>
</dependency>
<dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>wicketstuff-restannotations-json</artifactId>
<version>9.13.0</version>
</dependency>
② APIの構成クラス作成(RestApi.java)
package com.mycompany.api.resource;
import java.util.ArrayList;
import java.util.List;
import org.wicketstuff.rest.annotations.MethodMapping;
import org.wicketstuff.rest.contenthandling.json.objserialdeserial.GsonObjectSerialDeserial;
import org.wicketstuff.rest.contenthandling.json.webserialdeserial.JsonWebSerialDeserial;
import org.wicketstuff.rest.resource.AbstractRestResource;
public class RestApi extends AbstractRestResource<JsonWebSerialDeserial> {
private static final long serialVersionUID = 1L;
private final List<RestApiBean> data = new ArrayList<>();
public RestApi() {
super(new JsonWebSerialDeserial(new GsonObjectSerialDeserial()));
data.add(new RestApiBean(1, "mail1@example.com", "password1"));
data.add(new RestApiBean(2, "mail2@example.com", "password2"));
data.add(new RestApiBean(3, "mail3@example.com", "password3"));
data.add(new RestApiBean(4, "mail4@example.com", "password4"));
}
@MethodMapping("/data")
public List<RestApiBean> getData() {
return data;
}
}
AbstractRestResourceを継承して実装を進めます。
@MethodMappingアノテーションで、urlとmethodを紐づけます。
③ Beanクラス作成(RestApiBean.java)
package com.mycompany.api.resource;
public class RestApiBean {
private int id;
private String email;
private String password;
public RestApiBean(int id, String email, String password) {
this.id = id;
this.email = email;
this.password = password;
}
public int getId()
{
return id;
}
public String getEmail()
{
return email;
}
public String getPassword()
{
return password;
}
}
名前、メアド、パスワードを管理してみます。
④ ⓷で作成したresourceをマウント(WicketApplication.java)
WebApplicationの継承クラス内でresourceをマウントします。
package com.mycompany.api;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.request.resource.ResourceReference;
import com.mycompany.api.resource.RestApi;
public class WicketApplication extends WebApplication{
/**
* @see org.apache.wicket.Application#getHomePage()
*/
@Override
public Class<? extends WebPage> getHomePage() {
return Index.class;
}
@Override
public void init() {
super.init();
mountResource("/api", new ResourceReference("restReference") {
private static final long serialVersionUID = 1L;
private RestApi restAPI = new RestApi();
@Override
public IResource getResource() {
return restAPI;
}
});
}
}
mountResource("/api", new ResourceReference("restReference") {
でクラスが/api、Methodが/dataにマッピングされるので、/api/dataで呼び出しが可能になります。
⑤ ページクラス(Index.java)
package com.mycompany.api;
import org.apache.wicket.markup.html.WebPage;
public class Index extends WebPage {
private static final long serialVersionUID = 1L;
}
今回ページは不要ですので、ダミーとしてIndex.htmlを作成しておきます。
(Index.html)
<!DOCTYPE html>
<html>
<head />
</html>
最終構成は以下になります。
■ カレントディレクトリ
│ pom.xml
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─mycompany
│ │ │ └─api
│ │ │ │ Index.html
│ │ │ │ Index.java
│ │ │ │ WicketApplication.java
│ │ │ └─resource
│ │ │ RestApi.java
│ │ │ RestApiBean.java
│ │ └─webapp
│ │ └─WEB-INF
│ │ web.xml
では、実行してみます。前回やったように、ターミナル(コマンドプロンプト)で「mvn jetty:run」
コマンドを実行してみましょう。以下のように出力があれば成功です。API呼び出しが可能になります。
$ mvn jetty:run
(省略)
[INFO] Started ServerConnector@7f73ce28{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
[INFO] Started ServerConnector@1d6751e3{SSL, (ssl, http/1.1)}{0.0.0.0:8443}
[INFO] Started @6654ms
[INFO] Started Jetty Server
では、ブラウザで確認してみます。ちゃんとJsonが返却されていますね。
Visual Studio CodeではREST APIを呼び出す便利な拡張機能があるので、それを利用してみましょう。
.http拡張子のファイル内にcurlコマンドを書いて、「Send Request」を押下すると実行してくれる優れものですね。また、注意書きにあるようにcurlコマンドのすべてのオプションを網羅している わけではないので注意が必要です。以下がサポートしているオプションになります。 また、curlについては、https://curl.se/を参照ください
-X、--request
-L、--location、--url
-H、--header(@ サポートなし)
-I, --head
-b、--cookie (cookie jar ファイルのサポートなし)
-u、--user(基本認証サポートのみ)
-d、--data、--data-ascii、--data-binary、--data-raw
ここまで来たので、ついでに登録(POST)/削除(DELETE)も追加してみましょう。
(RestApi.java)
package com.mycompany.api.resource;
(省略)
import org.wicketstuff.restutils.http.HttpMethod; ★追加
(省略)
@MethodMapping(value = "/data", httpMethod = HttpMethod.POST)
public RestApiBean AddData(@RequestBody RestApiBean requestBody) {
data.add(requestBody);
return requestBody;
}
@MethodMapping(value = "/data/{id}", httpMethod = HttpMethod.DELETE)
public void DelData(int id) {
data.remove(id-1);
}
}
POSTは、dataに追加、DELETEは指定されたidを削除します。なおバリデーションなどは行って おりませんので、興味がある人は追加してみてください。
それでは、REST Clientを利用して、curlコマンド実行してみます。まずは、POSTから実行してみます。
無事に成功しましたね。確認のため、GETをしてみます。POSTで登録したデータが返却されていますね。
では、DELETEしてみましょう。返却値がないのでわかりにくいですが、HTTPステータス200(成功)が 返却されているので成功していますね。
それでは、削除確認のためにGETを実行してみましょう。 POSTで登録したデータが消えていることが確認できました。
駆け足でApache WicketでREST APIの実装をしてみましたが、いかがでしょうか?
動かない場合はご愛敬ということでお許しください。
今回紹介したREST APIのサンプルプログラムをベースにバリデーションやDB登録などを拡張するのも
いいかもしれません。
いやいや、もっと効率よくプログラムかけるよと色々活用していただけるとこれ幸いです。
さて、次回は作ったものをローカル環境ではなく、実際の環境に近い環境で動かしてみたいと思います。今度は早めに執筆したいと思いますので、よろしくお願いします。
hidedx