Are you copying an old maven project every time you need a new one? Maybe a maven archetype is the solution for you! In this post we will create a maven archetype to quickly create a micronaut graphQL API.

A different guide on how to create an archetype is done by apache and is found here.

The setup of the resulting project is inspired by a previous post on micronaut and graphQL. The complete code of the maven archetype from this post is found on github here.

Archetype-ception

The easiest way to get a ready to go maven archetype is by using an archetype :P. You only need to have maven installed to use this following command.

mvn archetype:generate \
     -DarchetypeGroupId=org.apache.maven.archetypes \
     -DarchetypeArtifactId=maven-archetype-archetype \
     -DarchetypeVersion=1.4 \
     -DgroupId=nl.sybrenbolandit.maven \
     -DartifactId=graphql-api-archetype \
     -Dversion=1.0.0

The first three variables identify the exact maven archetype we will use. The latter three will be the groupId, artifactId and version of the project we are creating. Here we create an archetype for graphQL APIs.

Project files

Basically there are two steps in getting a file into the generated project. First we copy the file into the src/main/resources/archetype-resources directory.

Screenshot 2020 11 29 at 21.33.25 - MAVEN ARCHETYPE

Here I just copied all the files from the graphQL API project we took as our inspiration.

Next we have to add the files to a fileSet in the archetype-metadata.xml file. (In src/main/resources/META-INF/maven)

<fileSet filtered="true" packaged="true">
  <directory>src/main/java</directory>
</fileSet>
<fileSet filtered="true" packaged="true">
  <directory>src/test/java</directory>
</fileSet>
<fileSet>
  <directory>src/main/resources</directory>
</fileSet>

We see that the standard java maven directories are already added. I added the src/main/resources fileSet which holds for example the graphQL schema.

Packaged

Note that there are two flags on the fileSet that can be added. First we see the packaged flag. This indicates that this set contains java files that belong to a package. In our Application class we can see what this means.

package $package;

import io.micronaut.runtime.Micronaut;

public class Application {
...

The package variable comes available and can be used with the dollar sign. When the archetype is used this will be substituted with the package (defaults to the reformatted groupId).

Filtered

The other flag we see it the filtered flag. This is a more general version of the packaged flag. It indicates that in these files all available variables are substituted.

The most basic examples are the variables inputted by the archetype generate command. These are used in the pom file of the resulting project.

<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>

Properties

In addition to the properties we have already seen we can define our own custom properties. We have to define them in the archetype-metadata.xml, just like the file sets.

<requiredProperties>
  <requiredProperty key="return-value">
    <defaultValue>Name</defaultValue>
  </requiredProperty>
</requiredProperties>

Here we define the return-value property that will be the value that is returned by the resulting graphQL API. If no value is specified during the generation we default to Name.

We can use this property in all of our project files. For example in the readme.

# GraphQL API
Simple graphQL API always returning the value: ${return-value}

Note: do not forget to add the filtered flag on the containing file set to enable the substitution.

<fileSet filtered="true">
  <directory></directory>
  <includes>
    <include>**/*.md</include>
  </includes>
</fileSet>

Usage

To use our fresh archetype we will use the same command that we used in the beginning of this post. Note that the first three variables now identify our archetype and we added the return-value property.

mvn archetype:generate \
     -DarchetypeGroupId=nl.sybrenbolandit.maven \
     -DarchetypeArtifactId=graphql-archetype \
     -DarchetypeVersion=1.0.0 \
     -DgroupId=nl.sybrenbolandit.graphql \
     -DartifactId=graphql-api \
     -Dversion=1.0.0 \
     -Dreturn-value=Sybren

The prompt is asking for our confirmation. If we do not agree, or if we do not supply all of the required properties we will go into interactive mode. We can specify all these properties on the fly.

Screenshot 2020 11 29 at 22.05.06 1024x133 - MAVEN ARCHETYPE

And there you go. A new graphQL API is created in seconds.

Screenshot 2020 11 29 at 22.05.55 1024x215 - MAVEN ARCHETYPE

Hopefully you are now able to create your own maven archetype and speed up your development process. Happy archetyping!