目次
- 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アプリケーションのプロジェクトを作成します。
コマンドプロンプトで下記のコマンドを入力します。
1 |
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のに追加します。
1 2 3 4 5 |
<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」の修正
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* 修正前 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」の修正
1 2 3 4 5 6 7 8 9 |
<!-- 修正前 --> <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」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
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のサーブレットをマッピングします。
1 2 3 4 |
<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」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
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」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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 の相互変換を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<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