---
title: "Vue.js、Spring Boot、Kotlin、GraphQLでモダンアプリケーションを構築する：第1部"
description: "フロントエンドにVue.js、バックエンドにSpring Boot、Kotlin、GraphQL APIを使用してモダンなウェブアプリケーションを構築する方法を紹介します。"
authors:
  - name: "Vladimir Fomene"
    url: "https://auth0.com/blog/authors/vladimir-fomene/"
date: "Aug 13, 2019"
category: "Developers,Tutorial,Vue.js"
tags: ["vue", "vue.js", "spring", "spring-boot", "web", "web開発", "spa", "シングルページアプリケーション", "graphql", "kotlin"]
url: "https://auth0.com/blog/jp-vuejs-spring-boot-kotlin-and-graphql-building-modern-apps-part-1/"
---

# Vue.js、Spring Boot、Kotlin、GraphQLでモダンアプリケーションを構築する：第1部



**概要：**今回は、2部連載シリーズでお届けするチュートリアルの第1部として、Vue.js、Spring Boot、Kotlin、GraphQLを使ってモダンなウェブアプリケーションを構築する方法をご紹介していきます。また、[Auth0](https://auth0.com/)を使用してバックエンドとフロントエンドアプリケーションを保護する方法についてもご紹介します。本シリーズで構築するアプリケーションの概要については、[このGitHubレポジトリ](https://github.com/vladimirfomene/MovieReviewBoard-Part-1)をご覧ください。

<include src="TweetQuote" quoteText="フロントエンドにVue.js、バックエンドにSpring Boot、Kotlin、GraphQL APIを使用してモダンなウェブアプリケーションを構築する方法を紹介します。"/>

## 前提条件

このチュートリアルを効果的に利用するには、システムに次のツールがインストールされている必要があります。

* JDK。[Kotlin](https://kotlinlang.org/)はJVMベースの言語で、JDK 8でSpring Bootをブートストラップするので、JDK 8以上がインストールされている必要があります。まだインストールしていない場合は、[こちら](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)からインストールしてください。
* フロントエンド開発用のNode.jsとNPM。Node.jsをインストールしていない場合は、[このリソースを参照してください](https://nodejs.org/en/download/)。インストールされているか確認するには、コマンドラインで`node -v`を実行すると、インストールされているNode.jsのバージョンが表示されます。NPMに関しては心配しなくて大丈夫です。たいていはNode.jsのインストール時に一緒にインストールされます。
* Vue CLI。まだインストールしていない場合はこの[リソース](https://cli.vuejs.org/guide/installation.html)を使用してインストールします。このページでは、システムにインストールされているVueのバージョンも調べられます。Vue CLIは、Vue.jsアプリケーションをスキャフォールディングするコマンドラインツールです。これはVueでReact.js用の[React Appの作成](https://facebook.github.io/create-react-app/)に相当するものです。
* 最後に、お好みのテキストエディタまたはIDE。お勧めは[VSCode](https://code.visualstudio.com/)または[IntelliJ IDEA](https://www.jetbrains.com/idea/)です。

こうしたツールに加えて、このチュートリアルでは[Spring BootとKotlin](https://spring.io/guides/tutorials/spring-boot-kotlin/)、[Vue.ks](https://vuejs.org/)、[Vuex](https://vuex.vuejs.org/)、[Vue Router](https://router.vuejs.org/)の基礎知識も必要となります。

## モダンなウェブアプリケーションのアーキテクチャ

モダンなウェブアプリケーションのほとんどは、バックエンドAPIと通信するシングルページアプリケーション（SPA）として構築されます。なぜSPAなのでしょうか？SPAは、サーバーがブラウザにシングルテンプレートを提供するブラウザベースのアプリケーションであり、他のページを動的にレンダリングするためにJavaScriptが使用されます。SPAはたいてい最初のページの読み込みに時間がかかりますが、その後はスムーズなユーザーエクスペリエンスを提供します。コンテンツのアップデートでは、SPAはJavaScriptでバックエンドAPIにクエリする必要があります。従来、APIは[RESTパターン](https://restfulapi.net/)に従って設計されてきましたが、現在では多くの人が、RESTよりも効率が良いという理由から[GraphQL](https://graphql.org/)を使ってAPIを構築しています。これは、GraphQLでは複数の連続したREST APIリクエストを1つのAPIリクエストに変換できるからです。

では、KotlinとVue.jsはなぜ使うのでしょうか？
* Kotlinでは開発者の生産性アップを図れる。
* Vue.jsはドキュメンテーションが優れている。

## 構築するアプリケーション

このシリーズでは、ユーザーがお気に入りの映画を鑑賞して監督情報を表示し、評価することのできる"Moview Review Board"というアプリケーションを構築していきます。すでにシリーズのタイトルからお分かりかと思いますが、Vue.js、Vuex、Vue Router、VueのEvent BusでSPAを構築し、Spring Boot、Kotlin、GraphQLでバックエンドAPIを構築します。

## Spring Bootアプリケーションのブートストラップ

では、構築するアプリケーションが分かったところで、[Spring Initializr](https://start.spring.io/)に話を移して、必要なツールとライブラリを選んでいきましょう。Spring Initializrページでは、フォームで次のアイテムを選択する必要があります。

* Project：Gradle Project
* Language：Kotlin
* Spring Boot：2.1.5
* Group： com.example
* Artifact：MovieReviewBoard

![Spring Initializrの設定](https://images.ctfassets.net/23aumh6u8s0i/4ZaDmLOWqJDvkrHarICuEz/a65f7827349e3c78f82d41a6d71a307c/spring-initializr-settings)

次に"Dependencies"セクションで、`Web`、`H2`、`JPA`ライブラリなどの検索ボックスを使用します。

![Dependenciesの設定](https://images.ctfassets.net/23aumh6u8s0i/59l1UrO3ffnwTvfGkpAuHa/b4ca66832f086876cd7037bf55f582bc/dependencies-settings)

それではプロジェクトを生成してください。するとブラウザで.zipファイルがダウンロードされます。このフォルダを解凍して、そこに**backend**フォルダを作成します。このbackendフォルダへのパスは`MovieReviewBoard/backend`とします。そして、**MovieReviewBoard**フォルダのすべてのコンテンツをbackendフォルダに入れます。これでbackendフォルダのコンテンツを好みのSpring Boot IDEにロードできるようになります。

>**注：**デフォルトでは、Spring Bootのservletコンテナはポート8080で待機するため、システム内の他のプログラムはそのポート番号で待機できなくなります。残念ながらWebpack（Vue.jsが使用するサーバー）もポート8080で実行されるので、同時に両方のプログラムを実行することはできなくなります。この問題を解決するには、アプリケーション内の`/MovieReviewBoard/backend/src/main/resources/application.properties`ファイルに移動して`server.port=8888`を追加します。これでSpring Bootがポート8080ではなくポート8888で待機するようになります。
次に、`com.example.MovieReviewBoard`パッケージに`HelloWorldController.kt`を作成してSpring Bootアプリケーションにhelloworldエンドポイントを作成します。`package com.example.MovieReviewBoard`という行を新しいファイルの冒頭に加えてから、次のコードを追加します。

```kotlin
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.core.Ordered
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
import org.springframework.web.filter.CorsFilter
import java.util.*
import javax.servlet.Filter

@RestController
class HelloWorldController {
  
    @GetMapping("/helloworld")
    fun greet(): String {
        return "helloworld!"
    }
    
    @Bean
    fun simpleCorsFilter(): FilterRegistrationBean<*> {
        val source = UrlBasedCorsConfigurationSource()
        val config = CorsConfiguration()
        config.allowCredentials = true
        // *** 下記のURLはVueクライアントURLとポートに一致させる必要がある***
        config.allowedOrigins = Collections.singletonList("http://localhost:8080")
        config.allowedMethods = Collections.singletonList("*")
        config.allowedHeaders = Collections.singletonList("*")
        source.registerCorsConfiguration("/**", config)
        val bean = FilterRegistrationBean<Filter>(CorsFilter(source))
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE)
        return bean
    }
  }
```

>**注：**`simpleCorsFilter()`メソッドがバックエンドAPIにクロスオリジンのサポートを追加します。このメソッドは、サーバーが送信するHTTP応答に`Access-Control-Allow-Origin`ヘッダーが設定されます。このヘッダーの値を`http://localhost:8080`に設定すると、このドメインからサーバーへのリクエスト送信を許可することをブラウザに指示できます。 
これを設定したら、コマンドラインを使って`MovieReviewBoard/backend/`内で`./gradlew bootRun`を実行するか、IDEで実行してバックエンドサーバーを実行します。ブラウザで `http://localhost:8888/helloworld`に移動すると、次のページが表示されます。

![Helloworldエンドポイントページ](https://images.ctfassets.net/23aumh6u8s0i/71A2paZ0pYegUebhc4tJkE/e350f0da49240110b9985c1f3eda7bfb/helloworld-endpoint)

## Vue.jsアプリケーションのブートストラップ

バックエンドの構成要素が整ったので、次はVue CLIを使ってフロントエンドアプリケーションをスキャフォールディングする必要があります。上記の前提条件セクションにある指示に従って、Vue CLIがインストールされているか確認してください。アプリケーションをスキャフォールディングするには、ターミナルを開いて**MovieReviewBoard**ディレクトリに移動し、次のコマンドを実行します。

```bash
vue create frontend
```

ターミナルにダイアログが作成されて設定に関する質問が提示されるので、次のように応答します。 

![Vueスキャフォールディングの設定](https://images.ctfassets.net/23aumh6u8s0i/490OvS4g0A9BQDLlhzdS8k/c53e3a8c6201d1ac942bd65b769e8e49/vue-scaffold-settings)

最後の質問の答えを確認すると、Vue CLIがVueアプリケーションの入った**frontend**フォルダを生成します。次に、バックエンドAPIのhelloworldエンドポイントを使用するボタンを追加します。そのためには、`MovieReviewBoard/frontend/src/views/About.vue`ページを次のように変更する必要があります。

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <button @click="callAPI">Call API</button>
        <h2>{{ greeting }}</h2>
      </div>
    </template>

    <script>
    import axios from "axios";
    export default {
      name: "about",
      data() {
        return {
          greeting: ""
        };
      },
      methods: {
        callAPI() {
          axios
            .get("http://localhost:8888/helloworld")
            .then(resp => {
              this.greeting = resp.data;
            })
            .catch(err => {
              this.greeting = err;
            });
        }
      }
    };
    </script>

上記の.vueファイルによって、**About**ページのテンプレートにボタンが追加され、`@click`属性を`callAPI`に設定するときにこのボタンのonClickイベントハンドラーとして`callAPI()`メソッドも追加されます。**CallAPI**メソッドが呼び出されると、バックエンドからhelloworldエンドポイントが呼び出され、これに応答して**helloworld!** メッセージでテンプレートを更新する、greetingデータ属性が更新されます。このテストを行う前に、`axios`（バックエンドAPIを呼び出すために`callAPI()`で使用されるHTTPクライアントモジュール）を追加します。コマンドラインで`MovieReviewBoard/frontend/`ディレクトリに移動して、次を実行します。

```bash
npm install axios --save
```

この変更を行ったら、コマンドラインかIDEを使って、`MovieReviewBoard/frontend/`で`npm run serve`を実行してフロントエンドサーバーを起動し、`MovieReviewBoard/backend/`で`./gradlew bootRun`を実行してバックエンドサーバーを起動させます。2台のサーバーが起動したら、ブラウザで `http://localhost:8080/#/about` に移動して「**Call API**」ボタンをクリックします。するとサーバーからのhelloworldメッセージが表示されます。

![HelloWorldメッセージ](https://images.ctfassets.net/23aumh6u8s0i/2l0qxIscF1m30iHQSGV7On/07823b37edc156dcb51b8e9a55074e32/helloworld-from-server)

## Spring BootとVue.jsアプリケーションの保護

現時点ではバックエンドに誰でもアクセスできる状態にあります。これでは事業に差し障りがあるので、APIを保護しましょう。APIの保護には、[Auth0](https://auth0.com/)のようなアイデンティティ管理プロバイダが必要です。セキュリティにAuth0を使用するには、アカウントがない場合には[アカウントを作成](https://auth0.com/signup)し、アカウントがある場合には[ログイン](https://auth0.com/auth/login)する必要があります。

Auth0アカウントにサインアップしたら、Auth0でバックエンドAPIを表すAPIを作成して構成し、リクエストを認証する必要があります。これを行うには、[Auth0ダッシュボードのAPIセクション](https://manage.auth0.com/#/apis)に移動して「**Create API**」ボタンをクリックします。すると、ダッシュボードに入力の必要なフォームが表示されます。

* Name：これはAPIのラベルです（例えば「**Spring Boot Kotlin**」にします）。
* Identifier：これはAPIのURL識別子です（ここでは`http://localhost:8888`など、有効なURLに近いものにします）。
* Signing Algorithm：このフィールドにはRS256を選択します。

その後、「**Create**」ボタンをクリックしてAPIの作成を完了します。次に、`backend/build.gradle`ファイルを開いて次のコードを追加します。

```gradle
// ...

dependencies {
  // ...
  implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.1.3.RELEASE'
}

// ...
```

この依存関係により、OAuth 2.0.でAPIを保護する機能が加わります。このライブラリを使用するのに必要な設定を追加するには、2つの手順が必要です。まず最初に、`security`パッケージを`com.example.MovieReviewBoard`パッケージに作成し、そこに`SecurityConfig.kt`ファイルを作成します。その後、以下のコードを`com.example.MovieReviewBoard.security`の`SecurityConfig.kt`ファイルにコピーします。

```kotlin
package com.example.MovieReviewBoard.security

import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer

@Configuration
@EnableResourceServer
class SecurityConfig : ResourceServerConfigurerAdapter() {
  
    @Value("\${security.oauth2.resource.id}")
    private lateinit var resourceId: String
    
    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) {
        http.authorizeRequests()
                .mvcMatchers("/helloworld").authenticated()
                .anyRequest().permitAll()
    }
    
    @Throws(Exception::class)
    override fun configure(resources: ResourceServerSecurityConfigurer) {
        resources.resourceId(resourceId)
    }
  }
```

上記の`@EnableResourceServer`の注釈は、OAuth 2.0.で保護されたリソースサーバーに便利です。これによって、受信したリクエストを認証するSpring Securityフィルタが自動で有効になります。Spring Bootがこれを処理するには、`resourceId`とも呼ばれるAuth0 API識別子を登録して、どのエンドポイントを保護したいのか（ここでは`/helloworld`）を特定してやる必要があります。

次に、APIに送信されるアクセストークンを検証するために、`resourceId`とAPI用のエンドポイントを定義してパブリックキーを取得する必要があります。これには`MovieReviewBoard/backend/src/main/resources/application.properties`を開いて次の設定を追加します。

```java
# ...
security.oauth2.resource.id=<YOUR-AUTH0-API-IDENTIFIER>
security.oauth2.resource.jwk.keySetUri=https://<YOUR-AUTH0-DOMAIN>/.well-known/jwks.json
```

上記の手順を完了すると、APIの**helloworld**エンドポイントが保護されるようになります。両方のアプリケーションを実行してから、ブラウザで[http://localhost:8080/#/about](http://localhost:8080/#/about)に移動して「**Call API**」ボタンをクリックすると、401ステータスのエラーメッセージが表示されるはずです。このページは、**helloworld**エンドポイントでコンテンツを表示する権限がないことを示しています。ここでは次のようなaboutページが表示されるはずです。 

![認証されないリクエスト](https://images.ctfassets.net/23aumh6u8s0i/6dt3oPVVkIE8nHcLCLO4lx/663bd547f61d7784fcb5c124a39e7beb/unauthorized-request)

Auth0でAPIを保護したことで、APIにリクエストを送信するにはAuth0からアクセストークンを取得しなければならなくなりました。SPAでアクセストークンを取得するには、これもAuth0でSPAを保護する必要があります。Auth0でSPAの認証を実装するには、Auth0アプリケーションを作成することから始めなければいけません。そのためには、Auth0ダッシュボードの「Applications」ページに移動して、「**Create Application**」ボタンをクリックします。ボタンをクリックするとAuth0にダイアログが表示されます。そこにアプリケーションの名前（例えば"MovieReviewBoard"などにします）を入力して、アプリケーションのタイプにSPAを選択する必要があります。 

![Auth0アプリケーションの作成](https://images.ctfassets.net/23aumh6u8s0i/1XWSNa3xpbHqz2ulXi8hC5/3f72a263263f1cb9dcd2c740fed3af62/create-SPA-Auth0)

では、「**Create**」ボタンをクリックしてください。Auth0により新しいアプリケーションのQuick Startセクションにリダイレクトされます。そこから「Setting」タブをクリックして`http://localhost:8080/callback`を「**Allowed Callback URLs**」フィールドに、`http://localhost:8080`を「**Allowed Web Origins**」、「**Allowed Logout URLs**」、「**Allowed Origins（CORS）**」の各フィールドに追加します。「**Save Changes**」をクリックして設定を保存します。次に、SPAにAuth0を統合する必要があります。まず、プロジェクトのフロントエンドディレクトリで次のコマンドを実行して、アプリケーションに`auth0.js`をインストールします。

```bash
npm install --save auth0-js
```

これでプロジェクトにauth0.js依存関係ができるので、それを使用して認証サービスを作成する必要があります。これには`MovieReviewBoard/frontend/`に`auth`ディレクトリを作成して、そこに`authService.js`ファイルを作成します。最後に、`authService.js`に次のコードを追加します。

```js
import auth0 from "auth0-js";
import authConfig from "../auth_config.json";
import eventBus from "../event-bus";

const webAuth = new auth0.WebAuth({
  domain: authConfig.domain,
  redirectUri: `${window.location.origin}/callback`,
  clientID: authConfig.clientId,
  audience: authConfig.audience,
  responseType: "token id_token",
  scope: "openid profile email"
});

class AuthService {
  accessToken = null;
  idToken = null;
  profile = null;
  tokenExpiry = null;
  // ユーザーログインフローを開始する
  login(customState) {
    webAuth.authorize({
      appState: customState
    });
  }
  // Auth0からのコールバックリクエストを処理する
  handleAuthentication() {
    return new Promise((resolve, reject) => {
      webAuth.parseHash((err, authResult) => {
        if (err) {
          reject(err);
        } else {
          this.localLogin(authResult);
          resolve(authResult.idToken);
        }
      });
    });
  }
  localLogin(authResult) {
    this.idToken = authResult.idToken;
    this.profile = authResult.idTokenPayload;
    this.accessToken = authResult.accessToken;
    // JWT有効期限の時間を秒からミリ秒に変換する
    this.tokenExpiry = new Date(this.profile.exp * 1000);
    localStorage.setItem("loggedIn", "true");
    eventBus.$emit("login");
  }
}

export default new AuthService();
```

現時点ではこのコードは意味不明に見えるかもしれませんが、ここから詳しく説明していきます。上記のファイルは、まずはじめに`auth0-js`認証ライブラリ、そしてAuth0アプリケーションの設定の一部を含むJSONファイル`auth_config.json`（このファイルの作成方法は後ほど説明するのでご心配なく）とVueイベントバスをインポートします。その後、`auth_config.json`の設定を使用してAuth0ウェブ認証インスタンスを作成し、Auth0に**ID_トークン**、**アクセストークン**、**ユーザープロファイル**を戻すように指示します。上記の各メソッドの機能は次のとおりです。

* `login`:Auth0にログインフローを開始するよう指示します。
* `handleAuthentication()`:Auth0が認証を完了すると、Auth0ウェブ認証インスタンスで設定された`redirectUri`にリダイレクトされ、`id_token`、`access_token`、`expires_in`（アクセストークンの有効期限）がブラウザのURLに提供されます。このメソッドはURLからこれらの値を取得し、解析して`localLogin`を呼び出し、これをメモリに保存します。

どうも説明が多くて失礼しました！次は、`MovieReviewBoard/frontend/`に`auth_config.json`を作成し、そこにAuth0アプリケーションの設定を次のように追加します。

```json
{
	"domain": "<Auth0-domain>",
	"clientId": "<Auth0-App-ClientId>",
	"audience": "<Auth0-API-IDENTIFIER>"
}
```

その後、`MovieReviewBoard/frontend/`に`event-bus.js`ファイルを作成して次のコードを追加します。

```js
import Vue from "vue";
const EventBus = new Vue();
export default EventBus;
```

すると、アプリケーションはVueのイベントバスを使用してイベントの作成と処理が行えるようになります。`authService.js`ファイルにAuth0ウェブ認証インスタンスの`redirectUri`プロパティを定義しますが、このリダイレクトURLのルートとコンポーネントはまだ作成していません。この問題を解決するには、まず下記のように、`MovieReviewBoard/frontend/src/router.js`でルートを作成します。

```js
// ..................
import Callback from "./components/Callback.vue";

export default new Router({
  mode: "history",
  routes: [
    //..............
    {
      path: "/callback",
      name: "callback",
      component: Callback
    },
    //.....................
  ]
});
```

このファイルが**Callback**コンポーネントのルートをアプリケーションに追加し、ルーティングモードを履歴モードに変更します（[ルーティングモードの詳細はこちら](https://router.vuejs.org/guide/essentials/history-mode.html)）。次に、`MovieReviewBoard/frontend/src/components`ディレクトリに`Callback.vue`ファイルを作成して次のコードを追加します。

    <template>
      <div>Loading.............</div>
    </template>

    <script>
    import eventBus from "../../event-bus";
    import authService from "../../auth/authService";
    export default {
      name: "callback",
      methods: {
        handleLogin() {
          this.$router.push("/about");
        }
      },
      created() {
        authService.handleAuthentication();
        eventBus.$on("login", () => this.handleLogin());
      }
    };
    </script>

    <style scoped></style>

Auth0で認証後にこのコンポーネントを作成すると、認証サービスの`handleAuthentication()`メソッドにより解析されるURLで、Auth0のトークンが取得できます。`handleAuthentication()`は、`locallogin()`を通して**ログイン**イベントを生成します。このイベントはその後、aboutページにリダイレクトする`handlelogin()`を呼び出すことにより、上記の`created()`メソッドで処理されます。これでaboutページが表示され、認証も済んだので、`About.vue`ページを変更することでSpring Boot APIに認可リクエストを送ることができるようになりました。

    <!-- leaving everything else unchanged -->
    <script>
    import axios from "axios";
    import authService from "../../auth/authService";
    export default {
      name: "about",
      data() {
        return {
          greeting: "",
          accessToken: null
        };
      },
      created() {
        this.accessToken = authService.accessToken;
      },
      methods: {
        callAPI() {
          axios({
            method: "GET",
            url: "http://localhost:8888/helloworld",
            headers: { authorization: `Bearer ${this.accessToken}` }
          })
            .then(resp => {
              this.greeting = resp.data;
            })
            .catch(err => {
              this.greeting = err;
            });
        }
      }
    };
    </script>

APIへのHTTP呼び出しについては、トークンで認可ヘッダーを設定することに注意してください。ここまでの手順を完了すれば、アプリケーションがユーザーを認証できるようになるはずですね。それが実はまだなのです。認証プロセスを始動させるログインボタンをまだ追加していないのです。そのためには、`Home.vue`ページを次のように修正します。

    <template>
      <div class="home">
        <img alt="Vue logo" src="../assets/logo.png" /><br />
        <button @click="login">Login</button>
        <HelloWorld msg="Welcome to Your Vue.js App" />
      </div>
    </template>

    <script>
    // @は/srcへのエイリアス
    import HelloWorld from "@/components/HelloWorld.vue";
    import authService from "../../auth/authService";
    export default {
      name: "home",
      components: {
        HelloWorld
      },
      methods: {
        login() {
          authService.login();
        }
      }
    };
    </script>

テンプレートにはブレークとボタンタグが追加されていますね。ボタンタグには、ボタン上のクリックイベントを待機して、アプリケーションの認証プロセスを始動させる`login()`メソッドを呼び出すイベントリスナー`@click`があります。両方のサーバーを実行して認証し、「**Call API**」ボタンをクリックすると、次が表示されます。

![HelloWorldメッセージ](https://images.ctfassets.net/23aumh6u8s0i/2l0qxIscF1m30iHQSGV7On/07823b37edc156dcb51b8e9a55074e32/helloworld-from-server)

<include src="TweetQuote" quoteText="Vue.jsとSpring Bootアプリケーションは@Auth0を使って簡単に保護できます。"/>

## 終わりに

これでシリーズの第1部は終了です。今回はフロントエンドとバックエンドの両方をブートストラップすることで、第2部に向けて基礎作りができました。Auth0で保護し、フロントエンドがバックエンドからのデータをどう使用するかを説明しました。第2部では、GraphQL APIの構築、Vuexでのステート管理、Vue-Routerでのルーティング、そしてBootstrap、Google Fonts、Font AwesomeによるUIの完成を重点的に説明していきます。

