SpringBootとReactを連携させてデータをやり取りする具体的な手法
目次
SpringBootで作成したRestAPIをReactから手軽に呼び出す完全ガイド
SpringBootとReactを利用したウェブ開発の基本を押さえ、両技術を連携させる方法をわかりやすくガイドします。本記事では、両技術の基本的な知識からスタートして、APIの作成、フロントエンドからのAPIの呼び出し方法、そしてよくあるトラブルとその対処法について解説します。Webアプリケーション開発における両技術の連携は非常にポピュラーであり、この技術をマスターすることで、多くのWebサービスをバックエンドからフロントエンドまで一通り作成可能となります。
始める前に知っておきたいSpringBootとReactの基本知識
SpringBootとReactの基本的な特性とそれぞれの役割について理解を深めます。SpringBootはJavaをベースとしたバックエンド開発フレームワークであり、データベースとの連携やAPIの提供、ビジネスロジックの実装などを行います。一方でReactはフロントエンドライブラリで、ユーザインターフェースを構築し、ユーザと直接インタラクションを行います。また、バックエンド(この場合SpringBoot)が提供するAPIを呼び出し、ユーザにデータを表示する役割も担います。
Step by Step: SpringBootとReactを連携させてデータをやり取りする具体的な手法
このセクションでは、SpringBootとReactの連携における一連のステップを具体的に解説します。初めにAPIの実装方法からスタートし、次にReactでAPIをどのように呼び出すか、さらにCORS問題の対処法、最後に追加テクニックを順を追って説明します。実際のコードスニペットとともに、各ステップがどのように連携して機能するのかを明示的に示し、読者が実践を通して学べる内容になっています。
手順1: SpringBootでのAPI実装とテスト方法
API実装の始めに、まずは何を実現したいのかの計画をしっかりと立てましょう。計画ができたら、SpringBootを使用してAPIを実装します。ここでは、エンドポイントの設計、データベースとの連携方法、ビジネスロジックの処理方法について基本を押さえながら進めていきます。テストはAPI開発において非常に重要な要素です。適切なテストを行うことで、APIが期待通りに動作しているか確認し、フロントエンド開発をスムーズに進めることができます。実際のコード例とともに、基本的なテストの書き方も解説していきます。
Step by Step: SpringBootとReactを連携させてデータをやり取りする具体的な手法
このセクションでは、SpringBootとReactの連携における一連のステップを具体的に解説します。初めにAPIの実装方法からスタートし、次にReactでAPIをどのように呼び出すか、さらにCORS問題の対処法、最後に追加テクニックを順を追って説明します。実際のコードスニペットとともに、各ステップがどのように連携して機能するのかを明示的に示し、読者が実践を通して学べる内容になっています。
手順1: SpringBootでのAPI実装とテスト方法
API実装の始めに、まずは何を実現したいのかの計画をしっかりと立てましょう。計画ができたら、SpringBootを使用してAPIを実装します。ここでは、エンドポイントの設計、データベースとの連携方法、ビジネスロジックの処理方法について基本を押さえながら進めていきます。テストはAPI開発において非常に重要な要素です。適切なテストを行うことで、APIが期待通りに動作しているか確認し、フロントエンド開発をスムーズに進めることができます。実際のコード例とともに、基本的なテストの書き方も解説していきます。
// Spring Bootでの簡単なAPIの実装例 @RestController @RequestMapping("/api") public class ExampleController { @GetMapping("/greet") public ResponseEntity greet(@RequestParam String name) { String greeting = "Hello, " + name + "!"; return new ResponseEntity<>(greeting, HttpStatus.OK); } } // テストの実装例 @SpringBootTest @AutoConfigureMockMvc public class ExampleControllerTest { @Autowired private MockMvc mockMvc; @Test public void greet_ShouldReturnGreetingMessage() throws Exception { String name = "Spring Boot"; String expectedResponse = "Hello, Spring Boot!"; mockMvc.perform(get("/api/greet") .param("name", name)) .andExpect(status().isOk()) .andExpect(content().string(expectedResponse)); } }
上記のコードは、最も基本的な形でSpring Bootを利用したAPIとそのテストの実装を示しています。ExampleControllerクラスには/api/greetエンドポイントが定義され、クエリパラメータnameを受け取り、挨拶メッセージをレスポンスとして返します。また、ExampleControllerTestクラスには、このAPIエンドポイントをテストするための基本的な実装が含まれています。
手順2: ReactからSpringBoot APIへのアクセスとデータの取得方法
ReactからAPIを呼び出すプロセスは非常にシンプルです。しかし、そのシンプルなプロセスを理解し、実装することでフロントエンドとバックエンドがどのように通信を行うかをしっかり把握することが重要です。以下にReactからSpringBootで作成したAPIを呼び出す基本的な手順とコードの例を示します。
// ReactでのAPI呼び出し例 import React, { useEffect, useState } from 'react'; import axios from 'axios'; function App() { const greeting, setGreeting = useState(''); useEffect(() => { // APIエンドポイントのURLを設定 const apiUrl = 'http://localhost:8080/api/greet'; const params = { name: 'React' }; // APIを呼び出し、レスポンスをstateにセット axios.get(apiUrl, { params }) .then((response) => { setGreeting(response.data); }) .catch((error) => { console.error('Error fetching data: ', error); alert('Error fetching data'); }); }, ); return ( <div> <h1>{greeting}</h1> </div> ); } export default App;
このコード例では、Reactアプリケーションからaxiosを用いてAPIを呼び出し、そのレスポンスを画面に表示しています。useEffectフック内でAPIを呼び出しており、APIからのレスポンスはgreetingステートにセットされます。その後、レンダリング部分でこのステートを用いてデータを表示します。
このシンプルな手順を通じて、フロントエンドとバックエンドがどうやって通信を行っているのかを理解する基盤を築くことができます。次に、セキュリティ面やエラーハンドリングなどの観点から、より洗練されたAPI呼び出しの手法を学んでいくことで、プロダクションレベルのアプリケーションを作成する力が身につきます。
手順3: CORS問題への対処とフロントエンドからの安全なAPIアクセス
フロントエンドとバックエンドが異なるオリジン(プロトコル、ドメイン、ポートのいずれかが異なる)から来ている場合、ブラウザのセキュリティポリシー、特に同一オリジンポリシーによってAPIリクエストがブロックされてしまう可能性があります。これが通常CORS問題として知られています。CORS問題を解決するためには、バックエンド側で適切なヘッダーをレスポンスに含め、フロントエンドからのリクエストを許可する設定を行う必要があります。以下では、SpringBootでCORSを許可する基本的な設定と、フロントエンド(React)から安全にAPIアクセスを行う一例について解説します。
// Spring BootでのCORS設定例 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://localhost:3000") // Reactアプリのオリジン .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); } }; } }
上記コードは、Spring Bootを用いたCORSの設定例を示しています。ここでは、/api/** パスへのリクエストに対して、http://localhost:3000(Reactアプリのローカル開発サーバーのオリジン)からのリクエストを許可する設定を行っています。また、許可するHTTPメソッドやヘッダーも指定しています。
手順4: ReactでAPI呼び出し時の認証と認可の基本
Webアプリケーションでデータをフェッチする際、APIエンドポイントが認証と認可を要求する場合があります。認証はユーザーが誰であるかを識別するプロセスであり、認可はユーザーが許可されたリソースにアクセスしてよいかを判断するプロセスです。このセクションでは、Reactから認証情報を含めてAPIを呼び出す基本的な手法と、その際のセキュリティ面を考慮したベストプラクティスについて解説します。
// ReactでのAPI呼び出しに認証情報を含める例 import React, { useEffect, useState } from 'react'; import axios from 'axios'; function App() { const data, setData = useState(null); useEffect(() => { // APIエンドポイントのURLを設定 const apiUrl = 'http://localhost:8080/api/secure-data'; // 認証情報 const authToken = 'YOUR_AUTH_TOKEN'; // axiosのインスタンスを作成し、認証ヘッダーを設定 const axiosInstance = axios.create({ baseURL: apiUrl, headers: { Authorization: `Bearer ${authToken}` } }); // APIを呼び出し、レスポンスをstateにセット axiosInstance.get() .then((response) => { setData(response.data); }) .catch((error) => { console.error('Error fetching data: ', error); alert('Error fetching data'); }); }, ); return ( <div> <h1>Secure Data: {data}</h1> </div> ); } export default App;
このコードスニペットは、認証情報(トークン)をHTTPヘッダーに含めてAPIを呼び出す基本的なReactコンポーネントの例です。トークンは通常、ユーザーがログインした後にサーバーから受け取り、その後の認証が必要なAPIリクエストで使用します。なお、セキュリティの観点から、トークンは絶対にハードコードせず、安全な場所(例: 環境変数またはセキュアなストレージ)から取得するべきです。
手順5: トークンの安全な取り扱いとリスク軽減策に関する基本ガイドライン
トークンを扱う際は、漏洩によるリスクを考慮し、安全な保存と送信を行う必要があります。トークン漏洩は、不正な第三者がユーザーを偽装することを可能にし、セキュリティインシデントの原因となる可能性があるため、非常に重要なポイントです。以下に、トークンの安全な取り扱いとリスク軽減に関するいくつかの基本的なガイドラインとコードスニペットを提供します。
// React: トークンのセキュアな保存と取得 import React, { useEffect, useState } from 'react'; import axios from 'axios'; function App() { const data, setData = useState(null); useEffect(() => { // APIエンドポイントのURLを設定 const apiUrl = 'http://localhost:8080/api/secure-data'; // セキュアな方法でトークンを取得(実際には、環境変数やセキュアストレージから取得) const authToken = process.env.REACT_APP_AUTH_TOKEN; // axiosのインスタンスを作成し、認証ヘッダーを設定 const axiosInstance = axios.create({ baseURL: apiUrl, headers: { Authorization: `Bearer ${authToken}` } }); // APIを呼び出し、レスポンスをstateにセット axiosInstance.get() .then((response) => { setData(response.data); }) .catch((error) => { console.error('Error fetching data: ', error); alert('Error fetching data'); }); }, ); return ( <div> <h1>Secure Data: {data}</h1> </div> ); } export default App;
このコード例では、トークンを .env ファイルの REACT_APP_AUTH_TOKEN から取得しています。これは、Create React Appが提供する環境変数の機能を利用したものです。一般的に、フロントエンドで保存されているトークンは、攻撃者から見ることが可能なため、漏洩時のリスクを最小限にする手段として以下の点を注意してください:
短い有効期間 | トークンは短時間のみ有効である |
---|---|
HttpOnly クッキー | トークンを HttpOnly クッキーに保存し、JSからアクセス不可にする |
HTTPS | APIエンドポイントは常にHTTPSを使用して通信する |
手順6: Spring Boot APIエンドポイントの保護とセキュリティ強化
Spring Bootで作成されたAPIは、デフォルトでは認証なしでアクセス可能な状態になっています。したがって、エンドポイントを安全に保護し、不正アクセスを防ぐためのセキュリティ強化が必要となります。ここでは、Spring Securityを使用してAPIのセキュリティを強化し、JWT(JSON Web Token)による認証と認可の流れを実装する基本的な手法を紹介します。
// Spring Boot: JWT認証の基本的な設定 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; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() .authorizeRequests() .antMatchers("/api/open/**").permitAll() // 公開エンドポイント .antMatchers("/api/secure/**").authenticated() // 認証が必要なエンドポイント .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())); } }
このコードスニペットは、Spring Securityを用いてAPIエンドポイントの保護を設定する基本的な例を示しています。ここでは以下の構成がなされています:
- 全てのCORSリクエストを許可し、CSRF保護を無効化しています。
- “/api/open/**” のパスへのアクセスは認証なしで許可されています。
- “/api/secure/**” のパスへのアクセスは認証が必要となっています。
JWT認証フィルタが追加されています。ここでは具体的なフィルタの実装は省略されていますが、一般的にはこのフィルタ内でトークンのバリデーションが行われます。