データ]

  • リンク:/tag/spring-data-rest/[春のデータREST]


1概要

このチュートリアルでは、フロントエンドにAngularJS、バックエンドにSpring Data RESTを使用した簡単なCRUDアプリケーションの例を作成します。


2 RESTデータサービスの作成

永続性のサポートを作成するために、データモデルに対してCRUD操作を実行できるようにするSpring Data REST仕様を利用します。

RESTエンドポイントの設定方法に関する必要な情報はすべてリンクにあります:/spring-data-rest-intro[Spring Data RESTの紹介]。この記事では、導入チュートリアルのためにセットアップした既存のプロジェクトを再利用します。

永続化のために、メモリデータベースで

H2

を使用します。

データモデルとして、前の記事では

id



name

、および

email

プロパティと、

UserRepository

という名前のリポジトリインタフェースを使用して

WebsiteUser

クラスを定義しています。

このインターフェースを定義すると、SpringはRESTコレクションリソースとアイテムリソースを公開するためのサポートを作成するようになります。後で

AngularJS

から呼び出すので、利用可能なエンドポイントを詳しく見てみましょう。


2.1. コレクションリソース

すべてのユーザーのリストはエンドポイント

/users

で利用可能になります。このURLはGETメソッドを使用して呼び出すことができ、以下の形式のJSONオブジェクトを返します。

{
  "__embedded" : {
    "users" :[{
      "name" : "Bryan",
      "age" : 20,
      "__links" : {
        "self" : {
          "href" : "http://localhost:8080/users/1"
        },
        "User" : {
          "href" : "http://localhost:8080/users/1"
        }
      }
    },
...
   ]  }
}


2.2. アイテムのリソース

単一の

WebsiteUser

オブジェクトは、異なるHTTPメソッドと要求ペイロードを使用して

/users/\ {userID}

の形式のURLにアクセスすることで操作できます。


WebsiteUser

オブジェクトを取得するために、GETメソッドで

/users/\ {userID}

にアクセスできます。これは次の形式のJSONオブジェクトを返します。

{
  "name" : "Bryan",
  "email" : "[email protected]",
  "__links" : {
    "self" : {
      "href" : "http://localhost:8080/users/1"
    },
    "User" : {
      "href" : "http://localhost:8080/users/1"
    }
  }
}

新しい

WebsiteUser

を追加するには、POSTメソッドで

/users

を呼び出す必要があります。新しい

WebsiteUser

レコードの属性は、リクエスト本文にJSONオブジェクトとして追加されます。

{name: "Bryan", email: "br[email protected]"}

エラーがない場合、このURLはステータスコード201 CREATEDを返します。


WebsiteUser

レコードの属性を更新したい場合は、PATCHメソッドと新しい値を含むリクエストボディを使用してURL

/users/\ {UserID}

を呼び出す必要があります。

{name: "Bryan", email: "[email protected]"}


WebsiteUser

レコードを削除するには、DELETEメソッドでURL

/users/\ {UserID}

を呼び出します。エラーがなければ、ステータスコード204 NO CONTENTを返します。


2.3. MVC設定

アプリケーションにHTMLファイルを表示するための基本的なMVC設定も追加します。

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

    public MvcConfig(){
        super();
    }

    @Override
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}


2.4. クロスオリジンリクエストの許可

REST APIとは別に

AngularJS

フロントエンドアプリケーションをデプロイする場合は、クロスオリジンリクエストを有効にする必要があります。

Spring Data RESTはバージョン1.5.0.RELEASEからこれに対するサポートを追加しました。異なるドメインからのリクエストを許可するには、

@ CrossOrigin

アノテーションをリポジトリに追加するだけです。

@CrossOrigin
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}

その結果、RESTエンドポイントからの応答ごとに、

Access-Control-Allow-Origin

のヘッダーが追加されます。


3 AngularJSクライアントを作成する

CRUDアプリケーションのフロントエンドを作成するには、

AngularJS

(フロントエンドアプリケーションの作成を容易にする有名なJavaScriptフレームワーク)を使用します。


AngularJS

を使用するには、まず、

users.html

という名前のHTMLページに

angular.min.js

ファイルを含める必要があります。

<script
  src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js">
</script>

次に、RESTエンドポイントを呼び出して返されたデータを表示するAngularモジュール、コントローラ、およびサービスを作成する必要があります。

これらは

app.js

というJavaScriptファイルに配置され、これも

users.html

ページに含める必要があります。

<script src="view/app.js"></script>


3.1. Angular Service

まず、注入された

AngularJS


$ http

サービスを利用してサーバーを呼び出す

UserCRUDService

というAngularサービスを作成しましょう。各呼び出しは別々のメソッドに入れられます。


/users/\ {userID}

エンドポイントを使用してIDでユーザーを取得する方法の定義を見てみましょう。

app.service('UserCRUDService',['$http', function($http) {

    this.getUser = function getUser(userId) {
        return $http({
            method : 'GET',
            url : 'users/' + userId
        });
    }
}]);

次に、

/users

URLにPOSTリクエストを送信し、

data

属性のユーザー値を送信する

addUser

メソッドを定義しましょう。

this.addUser = function addUser(name, email) {
    return $http({
        method : 'POST',
        url : 'users',
        data : {
            name : name,
            email: email
        }
    });
}


updateUser

メソッドは上記のメソッドと似ていますが、

id

パラメータを持ち、PATCHリクエストを行います。

this.updateUser = function updateUser(id, name, email) {
    return $http({
        method : 'PATCH',
        url : 'users/' + id,
        data : {
            name : name,
            email: email
        }
    });
}


WebsiteUser

レコードを削除するためのメソッドはDELETEリクエストを行います。

this.deleteUser = function deleteUser(id) {
    return $http({
        method : 'DELETE',
        url : 'users/' + id
    })
}

最後に、ユーザーのリスト全体を取得するための方法を見てみましょう。

this.getAllUsers = function getAllUsers() {
    return $http({
        method : 'GET',
        url : 'users'
    });
}

これらのサービスメソッドはすべて

AngularJS

コントローラーによって呼び出されます。


3.2. 角度コントローラー


UserCRUDService

をインジェクトし、サービスメソッドを使用してサーバーから応答を取得し、

success

および

error

のケースを処理し、それをHTMLで表示するための応答データを含む

$ scope

変数を設定する

UserCRUDCtrl

AngularJS__コントローラーを作成します。ページ。


getUser(userId)

サービス関数を呼び出し、成功とエラーが発生した場合の2つのコールバックメソッドを定義する

getUser()

関数を見てみましょう。サーバー要求が成功すると、応答は

user

変数に保存されます。それ以外の場合は、エラーメッセージが処理されます。

app.controller('UserCRUDCtrl',['$scope','UserCRUDService',
  function ($scope,UserCRUDService) {
      $scope.getUser = function () {
          var id = $scope.user.id;
          UserCRUDService.getUser($scope.user.id)
            .then(function success(response) {
                $scope.user = response.data;
                $scope.user.id = id;
                $scope.message='';
                $scope.errorMessage = '';
            },
            function error (response) {
                $scope.message = '';
                if (response.status === 404){
                    $scope.errorMessage = 'User not found!';
                }
                else {
                    $scope.errorMessage = "Error getting user!";
                }
            });
      };
}]);


addUser()

関数は対応するサービス関数を呼び出し、応答を処理します。

$scope.addUser = function () {
    if ($scope.user != null && $scope.user.name) {
        UserCRUDService.addUser($scope.user.name, $scope.user.email)
          .then (function success(response){
              $scope.message = 'User added!';
              $scope.errorMessage = '';
          },
          function error(response){
              $scope.errorMessage = 'Error adding user!';
              $scope.message = '';
        });
    }
    else {
        $scope.errorMessage = 'Please enter a name!';
        $scope.message = '';
    }
}


updateUser()

および

deleteUser()

関数は上記のものと似ています。

$scope.updateUser = function () {
    UserCRUDService.updateUser($scope.user.id,
      $scope.user.name, $scope.user.email)
      .then(function success(response) {
          $scope.message = 'User data updated!';
          $scope.errorMessage = '';
      },
      function error(response) {
          $scope.errorMessage = 'Error updating user!';
          $scope.message = '';
      });
}

$scope.deleteUser = function () {
    UserCRUDService.deleteUser($scope.user.id)
      .then (function success(response) {
          $scope.message = 'User deleted!';
          $scope.User = null;
          $scope.errorMessage='';
      },
      function error(response) {
          $scope.errorMessage = 'Error deleting user!';
          $scope.message='';
      });
}

最後に、ユーザーのリストを取得して

users

変数に格納する関数を定義しましょう。

$scope.getAllUsers = function () {
    UserCRUDService.getAllUsers()
      .then(function success(response) {
          $scope.users = response.data.__embedded.users;
          $scope.message='';
          $scope.errorMessage = '';
      },
      function error (response) {
          $scope.message='';
          $scope.errorMessage = 'Error getting users!';
      });
}


3.3. HTMLページ


users.html

ページは、前のセクションで定義されたコントローラ関数と格納された変数を利用します。

まず、Angularモジュールを使うために、

ng-app

プロパティを設定する必要があります。

<html ng-app="app">

次に、コントローラの関数を使用するたびに

UserCRUDCtrl.getUser()

を入力しないようにするために、

ng-controller

プロパティを設定して

div

にHTML要素をラップできます。

<div ng-controller="UserCRUDCtrl">

操作したい

WebiteUser

オブジェクトの値を入力して表示するフォームを作成しましょう。これらはそれぞれ

ng-model

属性セットを持ち、それが属性の値にバインドされます。

<table>
    <tr>
        <td width="100">ID:</td>
        <td><input type="text" id="id" ng-model="user.id"/></td>
    </tr>
    <tr>
        <td width="100">Name:</td>
        <td><input type="text" id="name" ng-model="user.name"/></td>
    </tr>
    <tr>
        <td width="100">Age:</td>
        <td><input type="text" id="age" ng-model="user.email"/></td>
    </tr>
</table>

たとえば、

id

入力を

user.id

変数にバインドすると、入力の値が変更されるたびに、この値が

user.id

変数に設定されます。

次に、

ng-click

属性を使用して、定義した各CRUDコントローラ関数の呼び出しをトリガーするリンクを定義します。

<a ng-click="getUser(user.id)">Get User</a>
<a ng-click="updateUser(user.id,user.name,user.email)">Update User</a>
<a ng-click="addUser(user.name,user.email)">Add User</a>
<a ng-click="deleteUser(user.id)">Delete User</a>

最後に、ユーザーのリストを完全に名前で表示します。

<a ng-click="getAllUsers()">Get all Users</a><br/><br/>
<div ng-repeat="usr in users">
{{usr.name}} {{usr.email}}


4結論

このチュートリアルでは、

AngularJS



Spring Data REST

仕様を使用してCRUDアプリケーションを作成する方法を説明しました。

上記の例の完全なコードはhttps://github.com/eugenp/tutorials/tree/master/spring-data-rest[GitHubプロジェクト]にあります。

アプリケーションを実行するには、コマンド

mvn spring-boot:run

を使用して、URL

/users.html

にアクセスします。