Nablarchのコンテナ用アーキタイプを使って、RESTful Webサービスを試す

# What's？

少し、Nablarchの素振りをしておきたい、ということで。

ちょっとお題を設けて、イチから試してみたいと思います。


# やってみること

* Nablarchは5u18を使う
* コンテナ用のアーキタイプを使って、RESTful Webサービスプロジェクトを作成する
* アノテーションで動作するDIを使う
* データベースをH2からPostgreSQLに切り替える

参考） [Nablarch 5u18をリリースしました！](https://fintan.jp/?p=6043)


# 環境

今回の環境は、こちらです。

```shell
$ java --version
openjdk 11.0.9 2020-10-20
OpenJDK Runtime Environment (build 11.0.9+11-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.9+11-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 11.0.9, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-52-generic", arch: "amd64", family: "unix"


$ docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:02:52 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:01:20 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
```


# プロジェクトを作成する

Getting Startedを見てみます。

[Getting Started](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/web_service/rest/getting_started/index.html)

> 本格的なアプリケーションを作成する場合は ブランクプロジェクト から作成すること。

ブランクプロジェクトから始めた方が良さそうなので、ブランクプロジェクトにしましょう。

[ブランクプロジェクト](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/index.html)

Nablarch 5u18から、コンテナ用のサポートが入っているので、こちらを使います。JibでDockerイメージを作れます、と。

[Dockerコンテナ化](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/cloud_native/containerize/index.html)

セットアップ手順。

[コンテナ用RESTfulウェブサービスプロジェクトの初期セットアップ](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/setup_containerBlankProject/setup_ContainerWebService.html)

Windows用のバッチファイルがあるのですが、こちらの環境はLinuxなので、直接`maven-archetype-plugin:2.4:generate`を実行します。

```shell
$ mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate \
  -DinteractiveMode=false \
  -DarchetypeGroupId=com.nablarch.archetype \
  -DarchetypeArtifactId=nablarch-container-jaxrs-archetype \
  -DarchetypeVersion=5u18 \
  -DgroupId=com.example \
  -DartifactId=hello-nablarch-restful \
  -Dversion=0.0.1 \
  -Dpackage=com.example
```

できました。

```shell
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: nablarch-container-jaxrs-archetype:5u18
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: hello-nablarch-restful
[INFO] Parameter: version, Value: 0.0.1
[INFO] Parameter: package, Value: com.example
[INFO] Parameter: packageInPathFormat, Value: com/example
[INFO] Parameter: package, Value: com.example
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: hello-nablarch-restful
[INFO] Parameter: version, Value: 0.0.1
[INFO] project created from Archetype in dir: /path/to/hello-nablarch-restful
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.583 s
[INFO] Finished at: 2020-11-11T11:10:34+09:00
[INFO] ------------------------------------------------------------------------
```

プロジェクト内に移動。

```shell
$ cd hello-nablarch-restful
```

ざっとファイルを見てみます。

```shell
$ find -type f
./README.md
./pom.xml
./.gitignore
./h2/bin/h2-1.3.176.jar
./h2/bin/h2w.bat
./h2/bin/h2.sh
./h2/bin/h2.bat
./h2/db/SAMPLE.h2.db
./h2/db/SAMPLE.h2.db.org
./db/ddl/db2/create.sql
./db/ddl/db2/drop.sql
./db/ddl/sqlserver/create.sql
./db/ddl/sqlserver/drop.sql
./db/ddl/oracle/create.sql
./db/ddl/oracle/drop.sql
./db/ddl/postgresql/create.sql
./db/ddl/postgresql/drop.sql
./db/ddl/h2/create.sql
./db/ddl/h2/drop.sql
./db/data/db2/data.sql
./db/data/sqlserver/data.sql
./db/data/oracle/data.sql
./db/data/postgresql/data.sql
./db/data/h2/data.sql
./src/main/webapp/WEB-INF/web.xml
./src/main/resources/entity/data-model_sqlserver.edm
./src/main/resources/entity/data-model.edm
./src/main/resources/entity/data-model_postgresql.edm
./src/main/resources/entity/data-model_db2.edm
./src/main/resources/entity/data-model_oracle.edm
./src/main/resources/rest-boot.xml
./src/main/resources/env.config
./src/main/resources/META-INF/services/nablarch.core.repository.di.config.externalize.ExternalizedComponentDefinitionLoader
./src/main/resources/rest-component-configuration.xml
./src/main/resources/messages.properties
./src/main/resources/data-source.xml
./src/main/resources/log.properties
./src/main/resources/app-log.properties
./src/main/resources/common.config
./src/main/jib/usr/local/tomcat/conf/server.xml
./src/main/jib/usr/local/tomcat/conf/logging.properties
./src/main/java/com/example/entity/package-info.java
./src/main/java/com/example/entity/SampleUser.java
./src/main/java/com/example/package-info.java
./src/main/java/com/example/domain/package-info.java
./src/main/java/com/example/domain/SampleDomainBean.java
./src/main/java/com/example/domain/SampleDomainManager.java
./src/main/java/com/example/SampleAction.java
./src/main/java/com/example/dto/SampleUserListDto.java
./src/test/resources/log.properties
./src/test/resources/unit-test.xml
./src/test/resources/data/SAMPLE_USER.csv
./src/test/java/com/example/SampleApiTest.java
./src/test/java/com/example/SampleActionTest.java
```

構成は、こちらに説明があります。

[Mavenアーキタイプの構成](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/MavenModuleStructures/index.html)

* [pj-container-jaxrsプロジェクト](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/MavenModuleStructures/index.html#pj-container-jaxrs)
* [pj-jaxrsプロジェクト](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/MavenModuleStructures/index.html#pj-jaxrs)
* [pj-webプロジェクト](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/MavenModuleStructures/index.html#pj-web)

プロファイルを見てみましょう。

```shell
$ mvn help:all-profiles
[INFO] Scanning for projects...
[WARNING] The POM for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 is missing, no dependency information available
[WARNING] Failed to retrieve plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0: Plugin org.eclipse.m2e:lifecycle-mapping:1.0.0 or one of its dependencies could not be resolved: Failure to find org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced
[INFO] 
[INFO] -----------------< com.example:hello-nablarch-restful >-----------------
[INFO] Building hello-nablarch-restful 0.0.1
[INFO] --------------------------------[ war ]---------------------------------
[WARNING] The POM for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 is missing, no dependency information available
[WARNING] Failed to retrieve plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0: Plugin org.eclipse.m2e:lifecycle-mapping:1.0.0 or one of its dependencies could not be resolved: Failure to find org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced
[INFO] 
[INFO] --- maven-help-plugin:3.2.0:all-profiles (default-cli) @ hello-nablarch-restful ---
[INFO] Listing Profiles for Project: com.example:hello-nablarch-restful:war:0.0.1
  Profile Id: BACKUP (Active: false , Source: pom)
  Profile Id: gsp (Active: false , Source: pom)
  Profile Id: ossrh (Active: false , Source: pom)

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.106 s
[INFO] Finished at: 2020-11-11T11:06:10+09:00
[INFO] ------------------------------------------------------------------------
```

コンテナ用のアーキタイプには、環境向けのプロファイルの概念がないようです。

[コンテナの本番環境設定](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/CustomizeDB.html#container-production-config)

`env.config`に書かれた値を、環境変数で上書きするように設定するみたいですね。

プロジェクト作成時には、こんな感じになっています。

```shell
$ grep -vE '^$|^#' src/main/resources/env.config 
nablarch.db.jdbcDriver=org.h2.Driver
nablarch.db.url=jdbc:h2:./h2/db/SAMPLE
nablarch.db.user=SAMPLE
nablarch.db.password=SAMPLE
nablarch.db.schema=PUBLIC
nablarch.db.maxPoolSize=5
nablarch.db.minimumIdle=5
nablarch.db.connectionTimeout=30000
nablarch.db.idleTimeout=600000
nablarch.db.maxLifetime=1800000
nablarch.db.validationTimeout=5000
nablarch.codeCache.loadOnStartUp=false
```

サンプルのActionクラスもあるようなので

`src/main/java/com/example/SampleAction.java`

```java
package com.example;

import com.example.dto.SampleUserListDto;
import com.example.entity.SampleUser;
import nablarch.common.dao.EntityList;
import nablarch.common.dao.UniversalDao;
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;

/**
 * 疎通確認用のアクションクラス。
 *
 * @deprecated TODO 疎通確認用のクラスです。確認完了後、削除してください。
 */
@Path("/find")
public class SampleAction {

    /**
     * 検索処理。
     * <p>
     * 応答にJSONを使用する。
     * </p>
     *
     * @param req HTTPリクエスト
     * @return ユーザ情報(JSON)
     */
    @GET
    @Path("/json")
    @Produces(MediaType.APPLICATION_JSON)
    public EntityList<SampleUser> findProducesJson(HttpRequest req) {
        return UniversalDao.findAll(SampleUser.class);
    }

    /**
     * 検索処理。
     * <p>
     * 応答にXMLを使用する。
     * </p>
     *
     * @param req HTTPリクエスト
     * @return ユーザ情報(XML)
     */
    @GET
    @Path("/xml")
    @Produces(MediaType.APPLICATION_XML)
    public SampleUserListDto findProducesXml(HttpRequest req) {
        EntityList<SampleUser> sampleUserList = UniversalDao.findAll(SampleUser.class);
        return new SampleUserListDto(sampleUserList);
    }

}
```

とりあえず、疎通確認のやり方に沿ってみましょう。

[疎通確認](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/setup_containerBlankProject/setup_ContainerWebService.html#firststepcontainerwebservicestartuptest)

まずは、Dockerイメージを作成。

```shell
$ mvn package jib:dockerBuild -DskipTests=true
```

できました、と。

```shell
$ docker image ls | grep hello
hello-nablarch-restful             0.0.1               a4b772a979de        50 years ago        448MB
hello-nablarch-restful             latest              a4b772a979de        50 years ago        448MB
```
初期設定でのベースイメージは、Tomcatのものが使われます。

[コンテナイメージを作成する](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/setup_containerBlankProject/setup_ContainerWeb.html#firststepbuildcontainerwebdockerimage)

起動してみます。

```shell
$ docker container run -it --rm -p 8080:8080 -v `pwd`/h2:/usr/local/tomcat/h2 hello-nablarch-restful:0.0.1
```

確認。とりあえずOKのようです。

```shell
$ curl localhost:8080/find/json
[{"userId":1,"kanjiName":"名部楽太郎","kanaName":"なぶらくたろう"},{"userId":2,"kanjiName":"名部楽次郎","kanaName":"なぶらくじろう"}]
```

ちなみに、この手順でVolumeの指定を忘れるとデータベースが見えなくなって失敗します（自分が見落としててハマった）。

```
-v `pwd`/h2:/usr/local/tomcat/h2
```

[コンテナイメージを実行する](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/setup_containerBlankProject/setup_ContainerWeb.html#firststepruncontainerwebdockerimage)


# XML-Less DI Configuration

次に、軽くDIを使ってみましょう。アノテーションを使ったDIができるようなので、こちらを使います。

[アノテーションを付与したクラスのオブジェクトを構築する](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/libraries/repository.html#repository-inject-annotation-component)

`AnnotationComponentDefinitionLoader`クラスのサブクラスを作成するようです。

置き場所はどうするもんだろう？と思ったので、以下を参考に。

[SPA + REST API構成のサービス開発リファレンス](https://fintan.jp/?p=5952)

[https://github.com/Fintan-contents/example-chat/blob/master/backend/src/main/java/com/example/system/nablarch/di/ExampleChatComponentDefinitionLoader.java](https://github.com/Fintan-contents/example-chat/blob/master/backend/src/main/java/com/example/system/nablarch/di/ExampleChatComponentDefinitionLoader.java)

まあ、結果としては単純にしておきました。

`src/main/java/com/example/system/HelloRestComponentDefinitionLoader.java`

```java
package com.example.system;

import nablarch.core.repository.di.config.externalize.AnnotationComponentDefinitionLoader;

public class HelloRestComponentDefinitionLoader extends AnnotationComponentDefinitionLoader {
    @Override
    protected String getBasePackage() {
        return "com.example";
    }
}
```

`getBasePackage`メソッドで、スキャン対象のパッケージを返します。

これを、ServiceLoaderの仕掛けに組み込むのですが、対象のファイルはすでにあるみたいなので

`src/main/resources/META-INF/services/nablarch.core.repository.di.config.externalize.ExternalizedComponentDefinitionLoader`

```
nablarch.core.repository.di.config.externalize.OsEnvironmentVariableExternalizedLoader
nablarch.core.repository.di.config.externalize.SystemPropertyExternalizedLoader
```

こちらに追記。

```
nablarch.core.repository.di.config.externalize.OsEnvironmentVariableExternalizedLoader
nablarch.core.repository.di.config.externalize.SystemPropertyExternalizedLoader
com.example.system.HelloRestComponentDefinitionLoader
```

サンプルにあった、データを取得処理を移したクラスを作成。`@SystemRepositoryComponent`アノテーションを付与しておきます。

`src/main/java/com/example/service/UserService.java`

```java
package com.example.service;

import com.example.entity.SampleUser;
import nablarch.common.dao.EntityList;
import nablarch.common.dao.UniversalDao;
import nablarch.core.repository.di.config.externalize.annotation.SystemRepositoryComponent;

@SystemRepositoryComponent
public class UserService {
    public EntityList<SampleUser> findUsers() {
        return UniversalDao.findAll(SampleUser.class);
    }
}
```

で、これを使うActionクラスを作成。

`src/main/java/com/example/HelloAction.java`

```java
package com.example;

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

import com.example.entity.SampleUser;
import com.example.service.UserService;
import nablarch.common.dao.EntityList;
import nablarch.core.repository.di.config.externalize.annotation.SystemRepositoryComponent;

@SystemRepositoryComponent
@Path("/hello")
public class HelloAction {
    UserService userService;

    public HelloAction(UserService userService) {
        this.userService = userService;
    }

    @GET
    @Path("/json")
    @Produces(MediaType.APPLICATION_JSON)
    public EntityList<SampleUser> users() {
        return userService.findUsers();
    }
}
```

コンストラクタで、コンポーネントを受け取るようにしておきます、と。

```java
    public HelloAction(UserService userService) {
        this.userService = userService;
    }
```

ActionクラスをDIコンテナ管理するためには、追加で設定が必要な模様。

[ActionクラスをDIコンテナで管理する](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/libraries/repository.html#actiondi)

こちらを抜粋。

`src/main/resources/rest-component-configuration.xml`

```xml
  <!--パッケージマッピングの設定 -->
  <component name="packageMapping" class="nablarch.integration.router.PathOptionsProviderRoutesMapping">
    <property name="pathOptionsProvider">
      <component class="nablarch.integration.router.jaxrs.JaxRsPathOptionsProvider">
        <property name="applicationPath" value="${nablarch.webApi.applicationPath}"/>
        <property name="basePackage" value="${nablarch.commonProperty.basePackage}"/>
      </component>
    </property>
    <property name="methodBinderFactory">
      <component class="nablarch.fw.jaxrs.JaxRsMethodBinderFactory">
        <property name="handlerList">
          <component class="nablarch.integration.jaxrs.jersey.JerseyJaxRsHandlerListFactory"/>
        </property>
      </component>
    </property>
  </component>
```

`delegateFactory`として、`SystemRepositoryDelegateFactory`を追加します。

```xml
  <!--パッケージマッピングの設定 -->
  <component name="packageMapping" class="nablarch.integration.router.PathOptionsProviderRoutesMapping">
    <property name="pathOptionsProvider">
      <component class="nablarch.integration.router.jaxrs.JaxRsPathOptionsProvider">
        <property name="applicationPath" value="${nablarch.webApi.applicationPath}"/>
        <property name="basePackage" value="${nablarch.commonProperty.basePackage}"/>
      </component>
    </property>
    <property name="methodBinderFactory">
      <component class="nablarch.fw.jaxrs.JaxRsMethodBinderFactory">
        <property name="handlerList">
          <component class="nablarch.integration.jaxrs.jersey.JerseyJaxRsHandlerListFactory"/>
        </property>
      </component>
    </property>
    <property name="delegateFactory">
        <component class="nablarch.fw.handler.SystemRepositoryDelegateFactory"/>
    </property>
  </component>
```

ここまでやったら、再度Dockerイメージをビルドして、起動。

```shell
$ mvn package jib:dockerBuild -DskipTests=true
$ docker container run -it --rm -p 8080:8080 -v `pwd`/h2:/usr/local/tomcat/h2 hello-nablarch-restful:0.0.1 
```

確認。

```shell
$ curl localhost:8080/hello/json
[{"userId":1,"kanjiName":"名部楽太郎","kanaName":"なぶらくたろう"},{"userId":2,"kanjiName":"名部楽次郎","kanaName":"なぶらくじろう"}]
```

OKですね。


# データベースをPostgreSQLに変更する

最後に、使用するデータベースをH2からPostgreSQLに変更してみましょう。

[使用するRDBMSの変更手順](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/CustomizeDB.html)

> RDBMSには、接続に使用するユーザや、スキーマが作成済みであること

だということなので。

PostgreSQLは、Dockerイメージを使うことにします。

[postgres](https://hub.docker.com/_/postgres)

12.2以上でも、大丈夫でしょう…。

[稼動環境](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/nablarch/platform.html#nablarch)

プロジェクトの構成を眺めると、SQLファイルが含まれているようなので

[Mavenアーキタイプの構成](https://nablarch.github.io/docs/5u18/doc/application_framework/application_framework/blank_project/MavenModuleStructures/index.html)

UTF-8に変換します（Shift_JISで書かれてた…）。

```shell
$ iconv -f sjis -t utf-8 db/ddl/postgresql/create.sql -o db/ddl/postgresql/create.sql.utf8
$ iconv -f sjis -t utf-8 db/data/postgresql/data.sql -o db/data/postgresql/data.sql.utf8
```

PostgreSQL起動。

```shell
$ docker container run -it --rm --name postgres \
  -v `pwd`/db:/data/db \
  -e POSTGRES_USER=postgres_user \
  -e POSTGRES_PASSWORD=postgres_password \
  -e POSTGRES_DB=mydatabase \
  postgres:13.0
```

コンテナに入って、DDL実行とデータの登録。

```shell
$ docker container exec -it postgres bash
$ psql -U postgres_user -f /data/db/ddl/postgresql/create.sql.utf8 mydatabase
$ psql -U postgres_user -f /data/db/data/postgresql/data.sql.utf8 mydatabase
```

今回は、ホスト側のポートにバインドせずに、別ホストのように扱ってみることにしましょう。コンテナのIPアドレスを確認します。

```shell
$ docker container inspect postgres | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",
```

JDBCドライバーをH2からPostgreSQLのものに差し替えて

```xml
    <!-- TODO: プロジェクトで使用するDB製品にあわせたJDBCドライバに修正してください。 -->
    <!--
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <version>1.3.176</version>
      <scope>runtime</scope>
    </dependency>
    -->
    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
      <version>42.2.18</version>
      <scope>runtime</scope>
    </dependency>
```

接続設定を修正。環境変数で上書きしてもいいのですが、今回はこれで。

`src/main/resources/env.config`

```shell
$ grep nablarch.db src/main/resources/env.config 
#nablarch.db.jdbcDriver=org.h2.Driver
nablarch.db.jdbcDriver=org.postgresql.Driver

#nablarch.db.url=jdbc:h2:./h2/db/SAMPLE
nablarch.db.url=jdbc:postgresql://172.17.0.2:5432/mydatabase

#nablarch.db.user=SAMPLE
nablarch.db.user=postgres_user

#nablarch.db.password=SAMPLE
nablarch.db.password=postgres_password

#nablarch.db.schema=PUBLIC
nablarch.db.schema=public
```

コンテナイメージの作成。

```shell
$ mvn clean
$ mvn package jib:dockerBuild -DskipTests=true
```

起動。

```shell
$ docker container run -it --rm -p 8080:8080 hello-nablarch-restful:0.0.1
```

確認。

```shell
$ curl localhost:8080/hello/json
][{"userId":1,"kanjiName":"名部楽太郎","kanaName":"なぶらくたろう"},{"userId":2,"kanjiName":"名部楽次郎","kanaName":"なぶらくじろう"}]
```

できました、と。