gRPC + Spring Boot application compiling proto files as a dependency
Published: 2021-10-27 00:49:33

If you're working with gRPC you're probably also working with Protobuf. And manually sharing your proto files with clients may not scale well.

What if I tell you that you could have a separated project and share your proto files as gradle/maven dependencies? That's the main goal of this article. Of course there'll be many more ways do to it out there, but if you use this article as a guide to do better, I'll be really honored.

So, I created 2 projects on Github:

* https://github.com/lepsistemas/grpc-hexagonal-architecture-proto
* https://github.com/lepsistemas/grpc-hexagonal-architecture

Noticed the names? One of them ends with "-proto". Yes, that's the project where we'll keep the proto files related to the "grpc-hexagonal-architecture" service. Oh, you're telling me you also noticed the names "hexagonal architecture"? That's a talk for another article. Let's focus on sharing the proto files in this one. And similarly I created 2 maven projects with the very same names.

The structure of the "proto project" is really simple:

src
+---main
+---+---proto
+---+---+---common
+---+---+---+---messages.proto
+---+---+---service
+---+---+---+---task.proto
pom.xml

No java classes, no extra configuration, just a pom file and a src folder. But if you pay attention to the pom file you'll wanna look at two parts:

* The &lt;project.scm.id&gt;
* The maven-release-plugin

The &lt;project.scm.id&gt; tag only exists to support multiple Github users on the same machine. If you only have one user, please define it with the value "github.com". In my case, "github.com" refers to the repositories I use in my job and for my personal repositories I use "github-lepsistemas". Please, refer to this article if you need help with it: https://www.freecodecamp.org/news/manage-multiple-github-accounts-the-ssh-way-2dadc30ccaca/

The maven-release-plugin will allow you to create tags and releases for your project in Github. For that, you'll need to be working on a SNAPSHOT (&lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;) and then you need to execute the maven task:

```shell
mvn -B release:clean release:prepare release:perform
```

This will create tag and release 1.0.0 in Github and will increase your local pom to 1.0.1-SNAPSHOT version.

At this point you have a release available in Github and you could download it as a dependency in another project. We'll use it in "grpc-hexagonal-architecture", another maven project.

Along with the dependencies that the project needs to compile/test/run, you'll also need this under &lt;project&gt; tag:

```xml
<repositories>
     <repository>
         <id>jitpack.io</id>
         <url>https://jitpack.io</url>
     </repository>
</repositories>
```

This will allow you to download a dependency directly from Github.

Add the dependency under the &lt;dependencies&gt; tag:

```xml
<dependency>
    <groupId>com.github.lepsistemas</groupId>
    <artifactId>grpc-hexagonal-architecture-proto</artifactId>
    <version>1.0.0</version>
</dependency>
```

And configure the compiler like this under the &lt;plugins&gt; tag:

```xml
<plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.6.1</version>
    <configuration>
        <protocArtifact>com.google.protobuf:protoc:3.17.3:exe:${os.detected.classifier}</protocArtifact>
        <pluginId>grpc-java</pluginId>
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.41.0:exe:${os.detected.classifier}</pluginArtifact>
        <protoSourceRoot>${basedir}/../grpc-hexagonal-architecture-proto/src/main/proto/</protoSourceRoot>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>compile-custom</goal>
            </goals>
        </execution>
    </executions>
</plugin>
```

All set. Your new gRPC project has a dependency from another project that exposes only the proto files. If you have any doubts, please refer to the Github repositories or you can always ask me.