This section describes the hal/json structure of the metadata exposed by the initializr. Such metadata can be used by third party clients to provide a list of options and default settings that can be used to request the creation of a project.
Each third-party client is advised to set a User-Agent
header for each request
sent to the service. A good structure for a user agent is clientId/clientVersion
(i.e. foo/1.2.0
for the "foo" client and version 1.2.0
).
Any third party client can retrieve the capabilities of the service by issuing a
GET
on the root URL using the following Accept
header:
application/vnd.initializr.v2.1+json
. Please note that the metadata may evolve in a
non backward compatible way in the future so adding this header ensures the service
returns the metadata format you expect.
This is an example output for a service running at start.spring.io
:
request.
GET / HTTP/1.1 Accept: application/vnd.initializr.v2.1+json Host: start.spring.io
response.
HTTP/1.1 200 OK ETag: "1262473f5c28f970e1e42d107213b064" Content-Type: application/vnd.initializr.v2.1+json Cache-Control: max-age=604800 Content-Length: 4872 { "_links" : { "maven-build" : { "href" : "https://start.spring.io/pom.xml?type=maven-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated" : true }, "maven-project" : { "href" : "https://start.spring.io/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated" : true }, "gradle-build" : { "href" : "https://start.spring.io/build.gradle?type=gradle-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated" : true }, "gradle-project" : { "href" : "https://start.spring.io/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated" : true }, "dependencies" : { "href" : "https://start.spring.io/dependencies{?bootVersion}", "templated" : true } }, "dependencies" : { "type" : "hierarchical-multi-select", "values" : [ { "name" : "Core", "values" : [ { "id" : "web", "name" : "Web", "description" : "Web dependency description", "_links" : { "guide" : { "href" : "https://example.com/guide", "title" : "Building a RESTful Web Service" }, "reference" : { "href" : "https://example.com/doc" } } }, { "id" : "security", "name" : "Security" }, { "id" : "data-jpa", "name" : "Data JPA" } ] }, { "name" : "Other", "values" : [ { "id" : "org.acme:foo", "name" : "Foo", "_links" : { "guide" : [ { "href" : "https://example.com/guide1" }, { "href" : "https://example.com/guide2", "title" : "Some guide for foo" } ], "reference" : { "href" : "https://example.com/{bootVersion}/doc", "templated" : true } } }, { "id" : "org.acme:bar", "name" : "Bar" }, { "id" : "org.acme:biz", "name" : "Biz", "versionRange" : "1.2.0.BUILD-SNAPSHOT" }, { "id" : "org.acme:bur", "name" : "Bur", "versionRange" : "[1.1.4.RELEASE,1.2.0.BUILD-SNAPSHOT)" }, { "id" : "my-api", "name" : "My API" } ] } ] }, "type" : { "type" : "action", "default" : "maven-project", "values" : [ { "id" : "maven-build", "name" : "Maven POM", "action" : "/pom.xml", "tags" : { "build" : "maven", "format" : "build" } }, { "id" : "maven-project", "name" : "Maven Project", "action" : "/starter.zip", "tags" : { "build" : "maven", "format" : "project" } }, { "id" : "gradle-build", "name" : "Gradle Config", "action" : "/build.gradle", "tags" : { "build" : "gradle", "format" : "build" } }, { "id" : "gradle-project", "name" : "Gradle Project", "action" : "/starter.zip", "tags" : { "build" : "gradle", "format" : "project" } } ] }, "packaging" : { "type" : "single-select", "default" : "jar", "values" : [ { "id" : "jar", "name" : "Jar" }, { "id" : "war", "name" : "War" } ] }, "javaVersion" : { "type" : "single-select", "default" : "1.8", "values" : [ { "id" : "1.6", "name" : "1.6" }, { "id" : "1.7", "name" : "1.7" }, { "id" : "1.8", "name" : "1.8" } ] }, "language" : { "type" : "single-select", "default" : "java", "values" : [ { "id" : "groovy", "name" : "Groovy" }, { "id" : "java", "name" : "Java" }, { "id" : "kotlin", "name" : "Kotlin" } ] }, "bootVersion" : { "type" : "single-select", "default" : "1.1.4.RELEASE", "values" : [ { "id" : "1.2.0.BUILD-SNAPSHOT", "name" : "Latest SNAPSHOT" }, { "id" : "1.1.4.RELEASE", "name" : "1.1.4" }, { "id" : "1.0.2.RELEASE", "name" : "1.0.2" } ] }, "groupId" : { "type" : "text", "default" : "com.example" }, "artifactId" : { "type" : "text", "default" : "demo" }, "version" : { "type" : "text", "default" : "0.0.1-SNAPSHOT" }, "name" : { "type" : "text", "default" : "demo" }, "description" : { "type" : "text", "default" : "Demo project for Spring Boot" }, "packageName" : { "type" : "text", "default" : "com.example" } }
The current capabilities are the following:
groupId
, artifactId
, version
, name
,
description
and packageName
.Each top-level attribute (i.e. capability) has a standard format:
type
attribute that defines the semantic of the attribute (see below).default
attribute that defines either the default value or the reference to
the default value.values
attribute that defines the set of acceptable values (if any). This can
be hierarchical (with values
being held in values
). Each item in a values
array
can have an id
, name
and description
).The following attribute type
are supported:
text
: defines a simple text value with no option.single-select
: defines a simple value to be chosen amongst the specified options.hierarchical-multi-select
: defines a hierarchical set of values (values in
values) with the ability to select multiple values.action
: a special type that defines the attribute defining the action to use.Each action is defined as a HAL-compliant URL. For instance, the maven-project
type
templated URL is defined as follows:
Type link example.
{ "href" : "https://start.spring.io/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated" : true }
You can use Spring HATEOAS and the UriTemplate
helper in particular to generate an
URI from template variables. Note that the variables match the name of top-level
attribute in the metadata document. If you can’t parse such URI, the action
attribute of each type gives you the root action to invoke on the server. This
requires more manual handling on your end.
A dependency is usually the coordinates of a starter module but it can be just as well be a regular dependency. A typical dependency structure looks like this:
{ "name": "Display name", "id": "org.acme.project:project-starter-foo", "description": "What starter foo does" }
The name is used as a display name to be shown in whatever UI used by the remote
client. The id can be anything, really as the actual dependency definition is
defined through configuration. If no id is defined, a default one is built using the
groupId
and artifactId
of the dependency. Note in particular that the version is
never used as part of an automatic id.
Each dependency belongs to a group. The idea of the group is to gather similar
dependencies and order them. Here is a value containing the core
group to
illustrates the feature:
Dependency group example.
{ "name" : "Core", "values" : [ { "id" : "web", "name" : "Web", "description" : "Web dependency description", "_links" : { "guide" : { "href" : "https://example.com/guide", "title" : "Building a RESTful Web Service" }, "reference" : { "href" : "https://example.com/doc" } } }, { "id" : "security", "name" : "Security" }, { "id" : "data-jpa", "name" : "Data JPA" } ] }
Each dependency can have links (in a HAL-compliant format). Links are grouped by
"relations" that provide a semantic to the link. A link can also have a title and
its URI can be templated. At the moment, the only valid parameter is bootVersion
.
The official relations are:
guide
: link to an how-to or guide that explain how to get startedreference
: link to a section of a reference guide (documentation)The type
element defines what kind of project can be generated and how. For
instance, if the service exposes the capability to generate a Maven project, this
would look like this:
Project type example.
{ "id" : "maven-build", "name" : "Maven POM", "action" : "/pom.xml", "tags" : { "build" : "maven", "format" : "build" } }
You should not rely on the output format depending that information. Always use the
response headers that define a Content-Type
and also a Content-Disposition
header.
Note that each id has a related HAL-compliant link that can be used to generate a
proper URI based on template variables. The top-level type
has, as any other
attribute, a default
attribute that is a hint to select what the service consider
to be a good default.
The action
attribute defines the endpoint the client should contact to actually
generate a project of that type if you can’t use the HAL-compliant url.
The tags
object is used to categorize the project type and give hints to 3rd
party client. For instance, the build tag defines the build system the project is
going to use and the format tag defines the format of the generated content (i.e.
here a complete project vs. a build file. Note that the Content-type
header of the
reply provides additional metadata).
The packaging
element defines the kind of project that should be generated.
Packaging example.
{ "id" : "jar", "name" : "Jar" }
The obvious values for this element are jar
and war
.
The javaVersion
element provides a list of possible java versions for the project:
Java example.
{ "id" : "1.6", "name" : "1.6" }
The language
element provides a list of possible languages for the project:
Language example.
{ "id" : "groovy", "name" : "Groovy" }