投稿日
フロントエンドはサービス開発リファレンスを使って、バックエンドは自前で作成してみた
もくじ
はじめに
こんにちは。西日本テクノロジー&イノベーション室の樋尻です。
私の所属する西日本テクノロジー&イノベーション室では、2020年9月末に「SPA + REST API構成のサービス開発リファレンス(以下サービス開発リファレンス)」を公開しました。こちらは、シングルページアプリケーション(以下SPA)とREST APIから構成されるWebアプリケーションを開発する際に活用して頂けるコンテンツになっています。
前回のブログでは、自前で作成したフロントエンドとサービス開発リファレンスで作成したバックエンドをつないで、フロントエンドとバックエンドを疎結合にできる点をご紹介しました。
今回はそれとは反対に、バックエンドを「Spring」を使って実装し、サービス開発リファレンスで作成したフロントエンドとつないでみます。
- サービス開発リファレンスを使ってWebアプリケーションを作成してみよう<導入編>
- サービス開発リファレンスを使って1画面作成してみよう
- サービス開発リファレンスを使ってREST APIを1つ作成してみよう
- サービス開発リファレンスを使ってバリデーションしてみよう
- サービス開発リファレンスを使ってファイルダウンロードを実装してみよう
- サービス開発リファレンスを使ってCSRF対策をしてみよう
- サービス開発リファレンスの方式設計ガイドを使ってみよう
- バックエンドはサービス開発リファレンスを使って、フロントエンドは自前で作成してみた
- フロントエンドはサービス開発リファレンスを使って、バックエンドは自前で作成してみた(←今回の記事)
事前準備
1~6までの記事でご紹介した作業の完成状態をベースに作成しますので、こちらの作業がまだの方は実施してみてください。
バックエンド
プロジェクトの作成
バックエンドのフレームワークには「Spring」を使用します。
Springではプロジェクトの雛形を作成するためのSpring Initializrが提供されているため、これでバックエンドのプロジェクトを作成します。
ここでは以下の画面にある設定で作成しました。
作成するとZIPファイルのダウンロードが始まりますので、ダウンロードが完了したら解凍します。
解凍すると、プロジェクトの雛形になるフォルダが入っています。そのフォルダの名前を「backend-spring」に変更し、frontend
やbackend
と同じフォルダ階層に配置してください。
プロジェクトの配置が完了しましたら、backend-spring
ディレクトリで以下のコマンドを実行し、バックエンドを起動してみましょう。
$ mvn spring-boot:run
起動が完了したら、以下のURLにアクセスしてみましょう。以下のようなログイン画面が表示されていれば成功です。
http://localhost:8080/
確認が完了したらCtrl+C
でバックエンドを停止し、Todo画面を動かすために実装していきます。
ポート番号とコンテキストパスを変更
まずは、前回のブログまでに使用していたバックエンドのポート番号とREST APIのパスに合わせるため、ポート番号とコンテキストパスを変更します。
backend-spring/src/main/resources/application.properties
ファイルに、以下のプロパティを追加します。
server.port=9080
server.servlet.context-path=/api
REST APIの実装
続いて、Todo画面で使用するREST APIを実装します。
backend-spring/src/main/java
にcom.example.controller
パッケージを作成し、以下のTodosController
クラスを作成します。
package com.example.controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/todos")
public class TodosController {
@GetMapping
public List<TodoResponse> get() {
// 疎通の検証が目的のため、固定で返却する
return List.of(
new TodoResponse(1L, "やること1"),
new TodoResponse(2L, "やること2"),
new TodoResponse(3L, "やること3"));
}
@PostMapping
public TodoResponse post(@RequestBody PostRequest requestBody) {
// 疎通を検証が目的のため、入力値の検証はせず、IDは固定で返却する
return new TodoResponse(4L, requestBody.text);
}
public static class PostRequest {
public String text;
}
public static class TodoResponse {
public final Long id;
public final String text;
public TodoResponse(Long id, String text) {
this.id = id;
this.text = text;
}
}
}
前回のブログまでに使用していたバックエンドではDBに接続していましたが、今回はつなぐことを確認するだけの簡易な実装としています。
CORSの実装
SPA + REST API構成ではフロントエンドとバックエンドが異なるオリジンになるため、通信するためにはオリジン間リソース共有(以下CORS)を使用する必要があります。
サービス開発リファレンスでは最初からCORSの設定がされている状態でしたので、ここではSpring Securityで同様のCORS設定を実装します。 backend-spring/src/main/java
のcom.example
パッケージに、以下のWebSecurityConfig
クラスを作成します。
package com.example;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.List;
import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors(withDefaults());
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowedHeaders(List.of("Content-Type", "X-CSRF-TOKEN"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
CSRF対策の実装
前回のブログまでに使用していたバックエンドではCSRF対策を実装していましたので、ここではSpring Securityで同様のCSRF対策を実装します。
CSRFトークンの検証はSpring Securityが内部で行ってくれるため、CSRFトークンを取得するためのREST APIを実装します。 backend-spring/src/main/java
のcom.example.controller
パッケージに、以下のCsrfController
クラスを作成します。
package com.example.controller;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CsrfController {
@GetMapping("/csrf_token")
public CsrfToken csrf(CsrfToken token) {
return token;
}
}
Spring Securityのデフォルト設定ではCSRFトークンがセッションに保持されていますので、それをそのまま返しています。 ここで注意する点があり、前回のブログまでに使用していたバックエンドで作成したREST APIとは戻り値の型が異なるため、フロントエンドに返却するJSONの項目名も異なります。そのためフロントエンド側で項目名を合わせるための修正が必要になりますので、後ほどご紹介します。
起動と動作確認
ここまで実装できたら、backend-spring
ディレクトリで次のコマンドを実行してバックエンドを起動します。
$ mvn spring-boot:run
起動が完了したら、以下のURLにアクセスしてみましょう。CSRFトークン取得結果のJSONが表示されていれば、動作確認は完了です。
http://localhost:8080/api/csrf_token
フロントエンド
CSRFトークン取得時の項目名を変更
バックエンドの実装時にも触れましたとおり、CSRFトークン取得結果であるJSONの項目名が変わっているため、CSRFトークンの取得処理を修正します。
frontend/src/example/backend/BackendService.ts
ファイルにあるrefreshCsrfToken
関数を、以下のとおり修正します。
function refreshCsrfToken(): Promise<void> {
Logger.debug('call service of refreshCsrfToken');
return getCsrfToken().then(({ headerName, token}) => {
Logger.debug('headerName:', headerName, 'token:', token);
restClient.csrfTokenHeaderName = headerName;
restClient.csrfTokenValue = token;
});
}
起動と動作確認
修正が終わりましたら、frontend
ディレクトリで次のコマンドを実行し、フロントエンドを起動してみましょう。
自動でブラウザが立ち上がり、Top画面が表示されます。
以下のURLでTodo画面を開いて、Todoが表示されることやTodoを登録できることを確認します。
http://localhost:3000/todo
確認が完了しましたら、今回の実装については全て完了です。
まとめ
このように、Nablarch以外のフレームワークを使用したバックエンドと、サービス開発リファレンスを使用したフロントエンドをつなぐことができました。前回のブログと合わせて、SPA + REST API構成ではフロントエンドとバックエンドが疎結合になるという点についてご紹介しました。
これまで9回の連載でサービス開発リファレンスの基本的な利用方法をご紹介してきました。これまでご紹介した内容がサービス開発リファレンスをご活用頂くためのお役に立てば幸いです。
本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。