Fintan

サービス開発リファレンスを使ってWebアプリケーションを作成してみよう<導入編>

CONTENTS

はじめに

こんにちは。西日本テクノロジー&イノベーション室の齊藤です。

私の所属する西日本テクノロジー&イノベーション室では、2020年9月末に「SPA + REST API構成のサービス開発リファレンス(以下サービス開発リファレンス)」を公開しました。こちらは、シングルページアプリケーション(以下SPA)とREST APIから構成されるWebアプリケーションを開発する際に活用して頂けるコンテンツになっています。

このサービス開発リファレンスに関するブログがすでに公開されていますので、こちらもあわせてご覧ください。

この記事では、実際にサービス開発リファレンスのコンテンツを利用したWebアプリケーションの作成方法や、サンプルとして用意されている機能をご紹介します。
サービス開発リファレンスをどのように使ったらよいかわからない、どういったメリットがあるのかわからないといった方にご理解いただけるような内容を記事にします。

また、1つの記事にまとめるのではなく、連載記事として投稿予定ですのでお楽しみにしてください。

目次

サービス開発リファレンスを使ってWebアプリケーションを作成してみよう<導入編>

SPA + REST API構成のサービス開発リファレンス」のコンテンツのひとつである「example-chat」をベースに、SPAとREST APIで簡単なアプリケーションを作成してみます。

今回は単純に「Hello World」を表示します。

事前準備

example-chat」のプロジェクトをクローン、またはZipでダウンロードを行い、手元に用意します。

また、動作確認にあたって、こちらのページに記載してある「開発に必要なソフトウェア(NodeやMavenなど)」が必要になるため、未インストールの場合はインストールを行います。

フロントエンド(SPA)の作成

それではまずフロントエンド(SPA)を作成します。
SPAの実装には、ReactTypeScriptを使用します。

不要なサンプルコードの削除

example-chat は小さなチャットサービスを実装したコード例になっています。
チャットサービスを実現するために、チャットの画面や通知や認証といった機能もコード例としてありますので、まずは新しいアプリケーションを作成する際に不要なサンプル用のソースコードを削除します。

具体的には以下のファイルを削除します。

  • frontend/src/chat/components/pages配下すべてのファイル
  • frontend/src/chat/components/parts配下すべてのファイル
  • frontend/src/chat/components直下の以下ファイル
    • ApplyNotification.tsx
    • Mixin.tsx
    • Routing.tsx
    • WithLoginContext.tsx
    • WithSystemMessages.tsx
  • frontend/src/chat/context配下すべてのファイル

ディレクトリ等の変更

frontend/src/chat  chat というディレクトリ名を任意の名前に変更しましょう。
今回は example とします。

また、 frontend/public/index.html にチャットExample用のmetaタグ titleタグが設定してあるため、こちらも任意の説明に変更します。

<meta
  name="description"
  content="Hello World Example"
/>

~~~~~~

<title>Hello World</title>

コンポーネントの作成

次に、「Hello World」を表示するためのコンポーネントを追加します。

frontend/src/example/components/pages/HelloWorld.tsx

import React from 'react';

const HelloWorld: React.FC = () => {

  return (
      <div>Hello World!!</div>
  );
};

export default HelloWorld;

次に、今作成したコンポーネントを App.tsx で表示するようにします。

frontend/src/App.tsx

import React from 'react';
import { Logger } from './framework/logging';
import './App.css';
import HelloWorld from "./example/components/pages/HelloWorld";

const App = () => {
  Logger.debug('rendering App...');
  return (
      <HelloWorld />
  );
};

export default App;

動作確認

これで準備はできましたので、frontend ディレクトリで次のコマンドを打って動作確認をします。

$ npm install
$ npm start

自動でブラウザが立ち上がり、画面に Hello World!! と表示されました。
かなり簡単ですね。

※ 自動で立ち上がらない場合は以下URLをブラウザで表示してみてください。
http://localhost:3000/

バックエンド(REST API)の作成

それでは次にバックエンド(REST API)を作成します。
REST APIを実現するためのフレームワークとしてNablarchを選択しています。 NablarchはTISがOSSとして公開している社内標準フレームワークです。言語はJavaです。

不要なサンプルコードの削除

こちらもフロントエンドと同様に、example-chat の不要なサンプル用のソースコードである以下を削除します。

  • notifier配下すべてのファイル
  • backend/src/main/java/com/example/application配下すべてのファイル
  • backend/src/main/java/com/example/domain配下すべてのファイル
  • backend/src/main/java/com/example/infrastructure配下すべてのファイル
  • backend/src/main/java/com/example/presentation/restapi配下すべてのファイル
  • backend/src/main/java/com/example/system/nablarch/di/EventListenerRegister.java
  • backend/src/main/java/com/example/system/nablarch/handler/csrf/CsrfTokenEndpointHandler.java
  • backend/src/main/java/com/example/system/nablarch/handler/LoginCheckHandler.java
  • backend/src/main/java/com/example/system/nablarch/handler/RestApiErrorResponseHandler.java
  • backend/src/main/java/com/example/system/nablarch/interceptor配下すべてのファイル
  • backend/src/main/resources/com/example配下すべてのファイル
  • backend/src/main/resources/db/migration配下すべてのファイル
  • backend/src/test/java配下すべてのファイル
  • backend/src/test/resources/com/example配下すべてのファイル
  • backend/src/test/resources/db/testdata配下すべてのファイル

不要な設定の修正・削除

次に、以下の設定ファイルに残っている不要な設定を修正・削除します。

  • backend/pom.xml
  • backend/src/main/webapp/WEB-INF/web.xml
  • backend/src/main/resources/rest-component-configuration.xml

backend/pom.xml  artifactId を任意の名前に修正します。

<artifactId>example-backend</artifactId>

backend/src/main/webapp/WEB-INF/web.xml から以下記述を削除します。

<listener>
  <listener-class>com.example.system.nablarch.di.EventListenerRegister</listener-class>
</listener>

backend/src/main/resources/rest-component-configuration.xml の以下記述を修正します。

■ Before

<property name="methodBinderFactory">
  <component class="nablarch.fw.jaxrs.JaxRsMethodBinderFactory">
    <property name="handlerList">
      <component class="com.example.system.nablarch.jaxrs.BodyConvertHandlerListFactory">
        <property name="preHandlers">
          <list>
            <component class="com.example.system.nablarch.handler.LoginCheckHandler"/>
          </list>
        </property>
      </component>
    </property>
  </component>
</property>

■ After

<property name="methodBinderFactory">
  <component class="nablarch.fw.jaxrs.JaxRsMethodBinderFactory">
    <property name="handlerList">
      <component class="nablarch.integration.jaxrs.jersey.JerseyJaxRsHandlerListFactory"/>
    </property>
  </component>
</property>

backend/src/main/resources/rest-component-configuration.xml の以下記述をすべてコメントアウトします。

<component name="csrfTokenVerificationHandler" class="nablarch.fw.web.handler.CsrfTokenVerificationHandler" >
  <property name="verificationFailureHandler">
    <component class="com.example.system.nablarch.handler.csrf.CsrfTokenVerificationFailureHandler"/>
  </property>
</component>
<component name="csrfTokenEndpointHandler" class="com.example.system.nablarch.handler.csrf.CsrfTokenEndpointHandler" />

~~~~~~

<!-- CSRFトークンの発行や検証を行うために追加 -->
<component-ref name="csrfTokenVerificationHandler"/>

<!-- CSRFトークン取得APIのエンドポイント -->
<component class="nablarch.fw.RequestHandlerEntry">
  <property name="requestPattern" value="/api/csrf_token" />
  <property name="handler" ref="csrfTokenEndpointHandler" />
</component>

~~~~~~

<component class="com.example.system.nablarch.handler.RestApiErrorResponseHandler"/>

~~~~~~

<component-ref name="dbMigration" />

クラスの作成

次に Hello World のJSONを返却するクラスを作成します。
/api/helloWorld にアクセスすると {"text":"Hello World!!"} のようなJSONを返すようにします。

backend/src/main/java/com/example/presentation/restapi/hello/HelloWorldAction.java

package com.example.presentation.restapi.hello;

import nablarch.core.repository.di.config.externalize.annotation.SystemRepositoryComponent;
import nablarch.fw.ExecutionContext;
import nablarch.fw.web.HttpRequest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/helloWorld")
@SystemRepositoryComponent
public class HelloWorldAction {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public HelloWorldResponse get(HttpRequest request, ExecutionContext context) {
        return new HelloWorldResponse("Hello World!!");
    }

    public static class HelloWorldResponse {

        public String text;

        public HelloWorldResponse(String text) {
            this.text = text;
        }
    }
}

Docker Composeの設定

example-chat ではデータベースや外部サービスのミドルウェアを使用するため、DockerおよびDocker Composeを利用します。

このアプリケーションでは、PostgreSQLRedisを使用します。 次のように docker-compose.yml を修正します。

version: '3.7'

services:
  postgres:
    image: postgres:12
    restart: always
    environment:
      POSTGRES_PASSWORD: example
    ports:
      - 5432:5432
  redis:
    image: redis:5.0.6
    ports:
      - 6379:6379
    volumes:
      - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf
    command: redis-server /usr/local/etc/redis/redis.conf
networks:
  default:
    name: example-network

次のコマンドで起動します。

$ docker-compose up -d

次のようにdocker-compose psコマンドを実行してStateUpになっていれば起動成功です。

$ docker-compose ps
Name                 Command                        State     Ports                     
-----------------------------------------------------------------------------------------------------------------
example_postgres_1   docker-entrypoint.sh postgres    Up      0.0.0.0:5432->5432/tcp  
example_redis_1      docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp

動作確認

これで準備はできましたので、backend ディレクトリで次のコマンドを打って起動します。

$ mvn jetty:run

例外が発生することなく次のようなログが出力されると起動成功です。

[INFO] Started ServerConnector@114a18d6{HTTP/1.1,[http/1.1]}{0.0.0.0:9080}
[INFO] Started Server@75689d9c{STARTING}[10.0.0.alpha1] @6271ms

Hit <enter> to redeploy:

curl コマンドを実行するか、ブラウザで次のURLを開いてJSONが返ってくれば成功です。
http://localhost:9080/api/helloWorld

$ curl http://localhost:9080/api/helloWorld
{"text":"Hello World!!"}

SPAとREST APIをつないでみよう

それぞれの動作確認が完了しましたので、SPAからさきほど作成したREST APIを呼び出して画面に「Hello World」を表示させてみましょう。

SPAからREST APIを呼び出す

SPAからREST APIを呼び出すために BackendService を次のように修正します。

frontend/src/example/backend/BackendService.ts

import { RestClient, Logger } from 'framework';

const restClient = new RestClient();

const getHelloWorld = async () => {
  Logger.debug('call service of getHelloWorld');

  const response = await restClient.get('/api/helloWorld');
  Logger.debug(response);
  return response.json();
};

export default {
  getHelloWorld,
};

次に、「Hello World」を表示していたコンポーネントから BackendService を呼び出し、
返却されたレスポンスを画面に表示します。

frontend/src/example/components/pages/HelloWorld.tsx

import React, {useEffect, useState} from 'react';
import { Logger } from '../../../framework/logging';
import { BackendService } from '../../backend';

const HelloWorld: React.FC = () => {
  const [text, setText] = useState<string>('');

  useEffect(() => {
    BackendService.getHelloWorld()
        .then(response => {
          Logger.debug(response);
          setText(response.text);
        });
  }, []);

  return (
      <div>{text}</div>
  );
};

export default HelloWorld;

動作確認

これで準備はできましたので、frontend ディレクトリで次のコマンドを打って動作確認をします。
※ すでに起動している場合は、ブラウザをリロードするだけで大丈夫です。

$ npm start

自動でブラウザが立ち上がり、さきほどと同じように Hello World!! と表示されました。
※ 自動で立ち上がらない場合は以下URLをブラウザで表示してみてください。
http://localhost:3000/

SPAとREST APIのつなぎこみも簡単に実装することができました。

まとめ

今回は、サービス開発リファレンスを使った簡単なWebアプリケーション(SPA/REST API)の作成方法を導入編としてご紹介しました。
次回はより実践的に、タスク管理をするための簡易的な画面(Todo画面)を作成してみます。


本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。

このエントリーをはてなブックマークに追加


TIS株式会社
個人情報保護方針 個人情報の取り扱いについて 情報セキュリティ方針 当サイトのご利用にあたって

Copyright 2021 TIS Inc.keyboard_arrow_up