目次
- 1.RESTfulAPIとは
- 2.WebAPIの設計
- 2.1 前提条件
- 2.2 前提知識
- 2.3 設計
- 2.4 公開されているPIの例
- 3.Jerseyを使ったWebアプリの実装
- 3.1 開発環境
- 3.2 Jerseyのプロジェクト作成
- 3.3 リソースファイルの改造
1.RESTfulAPIとは
REST API (RESTful API) は、REST(Representational State Transfer)アーキテクチャに従い、 コンピュータで提供されるサービスとの対話を可能にするAPIです。RESTはプロトコルなど決められた仕様があるわけではなく、API設計のガイドラインです。
RESTの4原則(Roy Fielding氏が2000年に提唱)はWebAPIの設計で考えると、
①ステートレスなクライアント/サーバプロトコル
リクエスト(メッセージ)はその内容を理解するために必要な全ての情報を含むこと。このため、メッセージ間におけるセッションの状態を管理する必要がなく、シンプルな設計にできます。
②すべてのリソースに適用できる定義された操作のセット
情報(リソース)を操作できる命令(”GET”、”POST”、”PUT”、”DELETE” などに相当するもの)が定義されていること。
③リソースを一意に識別する「汎用的な構文」
すべてのリソースはUniform Resource Identifier (URI) で一意的に識別できること。
④情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
情報の一部として、別の状態や別の情報への参照を含めることができる。
(参考:Wikipedia「Representational State Transfer」)
2.WebAPIの設計
RESTアーキテクチャに従い、WebAPIを考えることとします。
2.1 前提条件
WebAPIは、通信ネットワークを介したリモートのコンピュータ(Webサーバ、又はHTTPサーバ)にあるリソースを要求するためのAPIです。Web APIでは通常、要求メッセージにHTTPを使用し、応答メッセージの構造を定義します。
応答メッセージの形式として、通常XMLまたはJSONがあります。ここでは、リクエストにHTTP、応答メッセージの構文としてJSON形式とします。
2.2 前提知識
(1)HTTPプロトコルについて
ブラウザからHTTPでWebサーバにコンテンツを要求するときの電文は下図のようになります。
HTTPプロトコルはクライアントからのリクエスト(要求)とサーバからのレスポンス(返信)でデータの受け渡しを行います。
下記にリクエストとレスポンスの構造を示します。
ブラウザとWebサーバ間で使うHTTPのメソッドはGETとPOSTの2つで以下のように使い分けています。
①GET
URLの後にデータ(テキストのみ)を付加して送信します。
このため、検索フォームをGET送信するとURLの末尾に「/?パラメーター=値&パラメーター=値・・・」が付加され、履歴から再度検索することなどができます。
②POST
POST送信はボディ部にデータ(テキスト、バイナリ)を付加するため、URIの履歴に残りません。履歴に残さないフォームの送信時に使います。
HTTPにはGET、POSTメソッドの他、PUT、DELETEなどがあります。
(参考)
・RFC 2616: Hypertext Transfer Protocol — HTTP/1.1
https://www.ietf.org/rfc/rfc2616.txt
(2)JSON形式
JSON(JavaScript Object Notationの略)はJavaScriptのオブジェクトの表記方法の一つでテキスト形式のファイルをJSONファイル(拡張子は.json)といいます。
JSONは{}の中にキーと値をコロンで区切って記述します。
キーは必ずダブルクォーテーションで囲む必要があります。
キーの値は、
・文字列 {“name”:”suzuki”}
・数値 {“id”:1}
・null {“id”:null}
・bool値 {“s1″:true,”s2”:false}
の型が使えます。
また、値を入れ子にするときは
・オブジェクト
{“id”:1,”mdata”:{“name”:”suzu”,”age”:50}}
・配列
{“id”:1,”code”:[100,300,700]}
のようにオブジェクトと配列の型が扱えます。
2.3 設計
(1)リソースを決定
APIの利用者が必要としている情報(リソース)を決めます。天気の情報では、観測地点(緯度経度)、気温、湿度、気圧などが該当します。
(2)リソースに対して提供する操作
一般ユーザ向けのサービスでは参照のみと思いますが、決められたメンバーを対象とするサービスでは参照、新規登録、更新、削除などが考えられます。
(3)リソースの構造
WebAPIで定義する操作をデータベースへの登録(新規、更新)、検索、削除を前提にする場合は、データベースの設計(データの正規化など)において、WebAPIの操作とリソースに対してWebサーバ側のデータが一意的に決まるようにしますが、WebAPIで扱うリソースの対象がデータベースにあるものとは限りません。WebAPIのリソース間の親子関係について不整合が生じないようにリソースの構造を決める必要があります。
(4)URI(Uniform Resource Identifier)の設計
リソースの操作はHTTPメソッドで指示するようにします。
APIと分かるようなURIにします。
2.4 公開されているAPIの例
(1)都道府県内市区町村一覧取得API
HTTPメソッド:GET
URI:
https://www.land.mlit.go.jp/webland/api/CitySearch?<パラメータ>
パラメータ:都道府県コード
(例)東京都内の市区町村一覧を取得する
https://www.land.mlit.go.jp/webland/api/CitySearch?area=13
(引用)
・API操作説明 – 土地総合情報システム – 国土交通省)
https://www.land.mlit.go.jp/webland/api.html
(2)NHK番組表API
HTTPメソッド:GET
URI:
https://api.nhk.or.jp/v2/pg/list/{area}/{service}/{date}.json?key={apikey}
パラメータ:
area:地域ID(3byte)
sercice:サービスID(2byte)
date:日付(YYYY-MM-DD形式、当日から1週間先までの日付を指定)
apikey:APIキー(32byte)、ユーザに割り当てられる
(例)area:130:東京、g1:NHK総合1
https://api.nhk.or.jp/v2/pg/list/130/g1/2021-12-04.json?key=・・・
(引用)
・NHK番組表API
https://api-portal.nhk.or.jp/
3.Jerseyを使ったWebアプリの実装
ここではJAX-RS(Java API for RESTfulServices)フレームワークであるJerseyを使ったRESTfulServicesを作成します。
3.1 開発環境
Windows10Pro(64bit)
下記のソフトがインストールされている
・Apache Maven 3.8.4
・Eclipse JavaEE IDE Version: 2020-12 (4.18.0)
・Java version “15.0.2”
3.2 Jerseyのプロジェクト作成
Jersey(ジャージー)はJAX-RSフレームワークの一つです。ここではjersey-quickstart-webappmavenアーキタイプを使用して、jerseyRESTful APIWebアプリケーションを作成します。
(1)Mavenによるプロジェクトの作成
Webアプリケーションのプロジェクトを作成します。
コマンドプロンプトで下記のコマンドを入力します。
mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-webapp -DarchetypeGroupId=org.glassfish.jersey.archetypes
ここでは、
grpupId:test
artifactId:jaxrs-sample1
とします。
下記のプロジェクトフォルダが作成されます。
MavenはJavaのビルドツールの一つでxmlファイルに記述することでライブラリのインストールなどが行えます。
(本サイト内のコンテンツ)
・Mavenプロジェクトの作成(javaビルドツール)
(2)Eclipseにインポート
①mvnコマンドで作成したプロジェクトフォルダをEclipseで使えるようにします。
> cd jaxrs-sample1
> mvn eclipse:eclipse
②Eclipseにインポート
ファイル>インポート
③Mavenプロジェクトに変換
プロジェクト・エクスプローラーでプロジェクトを選択し、右ボタンのメニューから構成>「Mavenプロジェクトへ変換」を選択します。
JAX-RSのプロジェクトにはデフォルトではサーブレットAPIが組み込まれないためエラーになりますが、ここではサーブレットは使わないため問題ありません。
JSP/サーブレットを使うときはpom.xmlのに追加します。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
④サーバを起動
エラーの原因はmavenプロジェクト生成時に作成されたClassファイル「MyResource.java」において、importで指定するライブラリがJakarta EEのものとなっていました。
また、jerseyのバージョンが3.xとなっていたため、2.xに修正します。
javaEE(JakartaEE)のJerseyのバージョン
Jakarta EE 9 :Jersey 3.x
Java EE8,EE11 :Jersey 2.x
・「MyResource.java」の修正
/* 修正前
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
*/
/* 修正後 */
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
:
・「pom.xml」の修正
<!-- 修正前 -->
<properties>
<jersey.version>3.0.3</jersey.version>
</properties>
<!-- 修正後 -->
<properties>
<jersey.version>2.22.1</jersey.version>
</properties>
「MyResource.java」と「pom.xml」を修正してリソースにアクセスできるようになりました。
(3)リソースファイルについて
・「MyResouce.java」
package test;
/*
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
*/
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Root resource (exposed at "myresource" path)
*/
@Path("myresource")
public class MyResource {
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* @return String that will be returned as a text/plain response.
*/
@GET
@Produces(MediaType.TEXT_PLAIN)
public Employee getIt() {
return "Got it!";
}
}
・アノテーション
①@Path(“myresource”)
URIは「http://localhost:8080/jaxrs-sample1/webapi/myresource」でリソースにアクセスできます。
@Pathはこのクラスをマッピングするパスを指定します。
また、web.xmlのでJerseyのサーブレットをマッピングします。
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
②HTTPリクエストのJavaメソッドへのマッピング用javax.ws.rsアノテーション
@GET:HTTPのGETメソッドでアクセスされたとき呼び出されるメソッドで、URIにより識別されるリソースをクライアントに送信します。
@PUT:URIで識別される特定のリソースの作成(主に更新)を行います。
@DELETE:URIで識別されるリソースを削除します。
@POST:URIで識別される特定のリソースの作成(主に新規)を行います。
@HEAD:GETと同じ役割でレスポンス・ヘッダーのみを返し、メッセージはありません。
③ @Produces(MediaType.TEXT_PLAIN)
サービスが返すメディアタイプを指定することで、指定された型式でクライアントに返すことができます。
3.3 リソースファイルの改造
jersey-quickstart-webappmavenアーキタイプではテキストを返すのみでしたが、URIで指定したパラメータに従ってリソース(JSONファイル)を返すように改造します。
(1)RESTAPIのURI仕様
・リクエスト
GET /webapi/myresource/{id}/{name}
・レスポンス
JSON形式{“id”:id,”name”:name}
(2)改造内容
・「MyResource.java」
package test;
/*
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
*/
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Root resource (exposed at "myresource" path)
*/
@Path("myresource")
public class MyResource {
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* @return String that will be returned as a text/plain response.
*/
@GET
//@Produces(MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{id}/{name}")
public Employee getIt(@PathParam("id") int id,@PathParam("name") String name) {
Employee employee = new Employee(id, name);
return employee;
//return "Got it!";
}
}
・「Employee.java」
package test;
public class Employee {
/** 番号 */
public int id;
/** 名前 */
public String name;
/**
* コンストラクタ
* @param id 番号
* @param name 氏名
*/
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
}
・「pom.xml」
Jersey(ジャージー)の拡張モジュール「jersey-media-json-jackson」の追加します。Java オブジェクトと JSON の相互変換を行います。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>jaxrs-sample1</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>jaxrs-sample1</name>
<build>
<finalName>jaxrs-sample1</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
-->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
</dependencies>
<properties>
<jersey.version>2.22.1</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
リクエストGET /webapi/myresource/{id}/{name}のレスポンスとして、JSON形式{“id”:id,”name”:name}が返ります。
(参考文献)
・JAX-RSフレームワーク
https://ja.wikipedia.org/wiki/JAX-RS
・Oracle® Fusion Middleware Oracle WebLogic Server RESTful Webサービスの開発と保護
2 RESTful Webサービスの開発
https://docs.oracle.com/cd/E92951_01/wls/RESTF/develop-restful-service.htm
・「EclipseではじめるJavaフレームワーク入門 第5版」
著者:掌田津耶乃 発行:株式会社秀和システム
The end