CLOVER🍀

That was when it all began.

Spring Initializrをcurlで呼び出して使う

これは、なにをしたくて書いたもの?

Spring Initializrを、curlで使ってみようかなということで。

できることは前々から知っていたのですが、自分でもちょっと試しておこうという気になりまして。

Spring Initializr

Spring Initializrは、Spring Bootプロジェクトの雛形を簡単に作成できるWebサイトです。

Spring Initializr

f:id:Kazuhira:20201005230239p:plain

ビルドツールとしてMavenやGradleを選択したり、パッケージ名やアーティファクト名を指定したり、依存関係を追加したり
することができます。

f:id:Kazuhira:20201005230404p:plain

最後にzipファイルを作成することができるので、これをダウンロードして展開して使うのが一般的な使い方なのかな、と。

GitHubリポジトリとドキュメント

Spring InitializrのGitHubリポジトリは、こちらです。

GitHub - spring-io/initializr: A quickstart generator for Spring projects

現在のSpring Initializrのバージョンは、0.9.1のようです。

GitHubリポジトリのREADME.mdを見てもいろいろわかるのですが、ドキュメントも存在しています。

Spring Initializr Reference Guide

バージョンを0.9.1に指定したものは、こちら。

Spring Initializr Reference Guide

このドキュメントには、Spring Initializr自体を自前で構築する内容まで記載されていたりします。

Configuration Guide

まあ、それはさておき、せっかくなのでドキュメントを見つつ使っていってみましょう。

CLIで使う

まずは、こちらですね。いきなりcurlを使ってプロジェクトを作成する例が書いてあります。

Command line support

こんなやつですね。

$ curl https://start.spring.io/starter.zip -d dependencies=web,devtools \
           -d bootVersion=2.1.9.RELEASE -o my-project.zip

パラメーターは、-dで指定して渡せばよさそうです。

ところで、現在のSpring Bootのバージョンは2.3.4.RELEASEです。

今回は使いませんが、Spring Boot CLIもCLIツールとしては使うことができます。

Spring Boot CLI support

もうちょっと、詳しく

これだけだとちょっと物悲しいので、もう少し追ってみましょう。API Guideを見てみます。

API Guide

以下のようにAcceptヘッダーに適切な値を指定することで、メタデータを見ることができます。

Service Capabilities

$ curl -H 'Accept: application/vnd.initializr.v2.2+json' https://start.spring.io | jq

この時に指定しているURLは、https://start.spring.ioです。ファイルパス等の指定はありません。

vX.Yと指定してあるのは、メタデータのバージョンですね。現在はv2.2が最新です。

なんですけど、単純にcurlでアクセスすると、使い方そのものが見れたりします。

$ curl https://start.spring.io

以下、表示される内容です。

バナー等々。

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
:: Spring Initializr ::  https://start.spring.io

This service generates quickstart projects that can be easily customized.
Possible customizations include a project's dependencies, Java version, and
build system or build structure. See below for further details.

The services uses a HAL based hypermedia format to expose a set of resources
to interact with. If you access this root resource requesting application/json
as media type the response will contain the following links:
+-----------------+------------------------------------------+
| Rel             | Description                              |
+-----------------+------------------------------------------+
| gradle-build    | Generate a Gradle build file.            |
| gradle-project  | Generate a Gradle based project archive. |
| maven-build     | Generate a Maven pom.xml.                |
| maven-project * | Generate a Maven based project archive.  |
+-----------------+------------------------------------------+

パラメーターとデフォルト値。

The URI templates take a set of parameters to customize the result of a request
to the linked resource.
+-----------------+------------------------------------------+------------------------------+
| Parameter       | Description                              | Default value                |
+-----------------+------------------------------------------+------------------------------+
| applicationName | application name                         | DemoApplication              |
| artifactId      | project coordinates (infer archive name) | demo                         |
| baseDir         | base directory to create in the archive  | no base dir                  |
| bootVersion     | spring boot version                      | 2.3.4.RELEASE                |
| dependencies    | dependency identifiers (comma-separated) | none                         |
| description     | project description                      | Demo project for Spring Boot |
| groupId         | project coordinates                      | com.example                  |
| javaVersion     | language level                           | 11                           |
| language        | programming language                     | java                         |
| name            | project name (infer application name)    | demo                         |
| packageName     | root package                             | com.example.demo             |
| packaging       | project packaging                        | jar                          |
| type            | project type                             | maven-project                |
| version         | project version                          | 0.0.1-SNAPSHOT               |
+-----------------+------------------------------------------+------------------------------+

依存関係。

The following section has a list of supported identifiers for the comma-separated
list of "dependencies".
+--------------------------------------+--------------------------------------------------------------+-------------------------------+
| Id                                   | Description                                                  | Required version              |
+--------------------------------------+--------------------------------------------------------------+-------------------------------+
| activemq                             | Spring JMS support with Apache ActiveMQ 'Classic'.           |                               |
|                                      |                                                              |                               |
| actuator                             | Supports built in (or custom) endpoints that let you monitor |                               |
|                                      | and manage your application - such as application health,    |                               |
|                                      | metrics, sessions, etc.                                      |                               |
|                                      |                                                              |                               |
| alibaba-nacos-config                 | Support for externalized configuration in a distributed      | >=2.2.0.RELEASE and <2.3.0.M1 |
|                                      | system, auto refresh when configuration changes.             |                               |
|                                      |                                                              |                               |
| alibaba-nacos-discovery              | Service discovery with Alibaba Nacos.                        | >=2.2.0.RELEASE and <2.3.0.M1 |
|                                      |                                                              |                               |
| alibaba-sentinel                     | Flow control and circuit breaking with Alibaba Sentinel.     | >=2.2.0.RELEASE and <2.3.0.M1 |
|                                      |                                                              |                               |
| amqp                                 | Gives your applications a common platform to send and        |                               |
|                                      | receive messages, and your messages a safe place to live     |                               |
|                                      | until received.                                              |                               |
|                                      |                                                              |                               |
| artemis                              | Spring JMS support with Apache ActiveMQ Artemis.             |                               |
|                                      |                                                              |                               |
| azure-active-directory               | Spring Security integration with Azure Active Directory for  | >=2.0.0.RELEASE and <2.4.0-M1 |
|                                      | authentication.                                              |                               |
|                                      |                                                              |                               |
| azure-keyvault-secrets               | Manage application secrets and keys.                         | >=2.0.0.RELEASE and <2.4.0-M1 |
|                                      |                                                              |                               |
| azure-storage                        | Azure Storage service integration.                           | >=2.0.0.RELEASE and <2.3.0.M1 |
|                                      |                                                              |                               |
| azure-support                        | Auto-configuration for Azure Services (Service Bus, Storage, | >=2.0.0.RELEASE and <2.4.0-M1 |
|                                      | Active Directory, Cosmos DB, Key Vault, and more).           |                               |
|                                      |                                                              |                               |
| batch                                | Batch applications with transactions, retry/skip and chunk   |                               |
|                                      | based processing.                                            |                               |
|                                      |                                                              |                               |
| cache                                | Provides cache-related operations, such as the ability to    |                               |
|                                      | update the content of the cache, but does not provide the    |                               |
|                                      | actual data store.                                           |                               |
|                                      |                                                              |                               |

〜省略〜

最後に、サンプルまで付いてます。

Examples:

To create a default demo.zip:
    $ curl https://start.spring.io/starter.zip -o demo.zip

To create a web project using Java 11:
    $ curl https://start.spring.io/starter.zip -d dependencies=web \
            -d javaVersion=11 -o demo.zip

To create a web/data-jpa gradle project unpacked:
    $ curl https://start.spring.io/starter.tgz -d dependencies=web,data-jpa \
           -d type=gradle-project -d baseDir=my-dir | tar -xzvf -

To generate a Maven POM with war packaging:
    $ curl https://start.spring.io/pom.xml -d packaging=war -o pom.xml

もう、これを見たらいいんじゃないでしょうかね。

こういうのを見ると、呼び出す時のURL(というか拡張子)で、zipかtar.gzを選べそうです。

  • https://start.spring.io/starter.zip
  • https://start.spring.io/starter.tgz

先ほどのメタデータやパラメーターなどを見ていた時と違って、こちらはstarter.zipまたはstarter.tgzとファイル名が
ついてくるので注意しましょう。

試してみる

というわけで、最後に軽く試してみます。

パラメーター名を覚えられないので、1度表示して

$ curl -s https://start.spring.io | grep -B 1 -A 18 Parameter
+-----------------+------------------------------------------+------------------------------+
| Parameter       | Description                              | Default value                |
+-----------------+------------------------------------------+------------------------------+
| applicationName | application name                         | DemoApplication              |
| artifactId      | project coordinates (infer archive name) | demo                         |
| baseDir         | base directory to create in the archive  | no base dir                  |
| bootVersion     | spring boot version                      | 2.3.4.RELEASE                |
| dependencies    | dependency identifiers (comma-separated) | none                         |
| description     | project description                      | Demo project for Spring Boot |
| groupId         | project coordinates                      | com.example                  |
| javaVersion     | language level                           | 11                           |
| language        | programming language                     | java                         |
| name            | project name (infer application name)    | demo                         |
| packageName     | root package                             | com.example.demo             |
| packaging       | project packaging                        | jar                          |
| type            | project type                             | maven-project                |
| version         | project version                          | 0.0.1-SNAPSHOT               |
+-----------------+------------------------------------------+------------------------------+

tgzでダウンロードし、そのまま展開してみます。

$ curl -s https://start.spring.io/starter.tgz \
  -d dependencies=web \
  -d groupId=org.littlewings \
  -d artifactId=initializr-example \
  -d packageName=org.littlewings.spring.initializr \
  -d baseDir=initializr-example | tar zxvf -

この形態の場合はbaseDirを省略するとカレントディレクトリにフラットに展開されるので、それが嫌な場合はbaseDirを
指定しましょう。

実行結果。

$ curl -s https://start.spring.io/starter.tgz \
  -d dependencies=web \
  -d groupId=org.littlewings \
  -d artifactId=initilizr-example \
  -d packageName=org.littlewings.spring.initializr \
  -d baseDir=initializr-example | tar zxvf -
initializr-example/
initializr-example/mvnw
initializr-example/.gitignore
initializr-example/HELP.md
initializr-example/.mvn/
initializr-example/.mvn/wrapper/
initializr-example/.mvn/wrapper/maven-wrapper.properties
initializr-example/.mvn/wrapper/MavenWrapperDownloader.java
initializr-example/.mvn/wrapper/maven-wrapper.jar
initializr-example/src/
initializr-example/src/test/
initializr-example/src/test/java/
initializr-example/src/test/java/org/
initializr-example/src/test/java/org/littlewings/
initializr-example/src/test/java/org/littlewings/spring/
initializr-example/src/test/java/org/littlewings/spring/initializr/
initializr-example/src/test/java/org/littlewings/spring/initializr/DemoApplicationTests.java
initializr-example/src/main/
initializr-example/src/main/java/
initializr-example/src/main/java/org/
initializr-example/src/main/java/org/littlewings/
initializr-example/src/main/java/org/littlewings/spring/
initializr-example/src/main/java/org/littlewings/spring/initializr/
initializr-example/src/main/java/org/littlewings/spring/initializr/DemoApplication.java
initializr-example/src/main/resources/
initializr-example/src/main/resources/application.properties
initializr-example/src/main/resources/templates/
initializr-example/src/main/resources/static/
initializr-example/pom.xml
initializr-example/mvnw.cmd

確認。

$ cd initializr-example
$ ./mvnw package -DskipTests=true
$ java -jar target/initilizr-example-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.4.RELEASE)

2020-10-06 00:01:04.042  INFO 18316 --- [           main] o.l.spring.initializr.DemoApplication    : Starting DemoApplication v0.0.1-SNAPSHOT on ikaruga with PID 18316 (/path/to/initializr-example/target/initilizr-example-0.0.1-SNAPSHOT.jar started by kazuhira in /path/to/initializr-example)
2020-10-06 00:01:04.046  INFO 18316 --- [           main] o.l.spring.initializr.DemoApplication    : No active profile set, falling back to default profiles: default
2020-10-06 00:01:05.154  INFO 18316 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-10-06 00:01:05.174  INFO 18316 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-10-06 00:01:05.174  INFO 18316 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.38]
2020-10-06 00:01:05.299  INFO 18316 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-10-06 00:01:05.300  INFO 18316 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1173 ms
2020-10-06 00:01:05.599  INFO 18316 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-10-06 00:01:05.802  INFO 18316 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-10-06 00:01:05.816  INFO 18316 --- [           main] o.l.spring.initializr.DemoApplication    : Started DemoApplication in 2.303 seconds (JVM running for 2.781)

こんな感じで。

個人的には、これくらい指定するといいのかなぁと思います。

$ curl -s https://start.spring.io/starter.tgz \
  -d bootVersion=... \
  -d javaVersion=... \
  -d name=... \
  -d groupId=... \
  -d artifactId=... \
  -d version=... \
  -d packageName=... \
  -d baseDir=... | tar zxvf -