Getting started with NetflixOSS Governator
NetflixOSS Governator is a set of Google Guice extensions to create REST services using Jersey.
Using Governator we can easily configure servers like Jetty and Tomcat in order to build microservices. We also can use set of guice modules to integrated with Archaius and Eureka-Client.
Governator is not opinionated, it's similar to Spring Boot in comparison. However, Governator is configured to work with Guice and not Spring framework.
Governator it's cool because you can define pretty much everything using java code and annotations in a declarative fashion. All code is configured in Guice so we can take benefit of Ioc and Dependency injection and end up creating solution more testable by nature.
Governator Features:
Using Governator we can easily configure servers like Jetty and Tomcat in order to build microservices. We also can use set of guice modules to integrated with Archaius and Eureka-Client.
Governator is not opinionated, it's similar to Spring Boot in comparison. However, Governator is configured to work with Guice and not Spring framework.
Governator it's cool because you can define pretty much everything using java code and annotations in a declarative fashion. All code is configured in Guice so we can take benefit of Ioc and Dependency injection and end up creating solution more testable by nature.
Governator Features:
- Classpath scanning
- Automatic binding
- Lifecycle management
- Configuration of field mapping
- Field validation
- Parallelized object warmup
Creating a Simple REST Service with Governator 1.x
First of all, we need to define our dependencies on build.gradle. So let's defined the dependencies.
build.gradle
build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: "java" | |
apply plugin: "application" | |
sourceCompatibility = 1.8 | |
targetCompatibility = 1.8 | |
mainClassName = "com.github.diegopacheco.netflix.pocs.governator.web.jersey.JerseyMain" | |
sourceSets { | |
main.java.srcDirs = ["src/main/java"] | |
} | |
repositories { | |
mavenCentral() | |
maven { | |
url "https://oss.sonatype.org/content/groups/public/" | |
} | |
} | |
dependencies { | |
compile([ | |
'com.netflix.governator:governator:1.17.4', | |
'com.netflix.governator:governator-annotations:1.17.4', | |
'com.netflix.governator:governator-jetty:1.17.4', | |
'com.netflix.governator:governator-jersey:1.17.4', | |
'javax.servlet:servlet-api:2.5', | |
'org.slf4j:slf4j-api:1.7.0', | |
'org.slf4j:slf4j-simple:1.7.0' | |
]) | |
} |
Now we can do the java code -- which is pretty easy.
JerseyMain.java
JerseyMain.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.diegopacheco.netflix.pocs.governator.web.jersey; | |
import java.util.Map; | |
import java.util.function.UnaryOperator; | |
import javax.inject.Named; | |
import javax.inject.Singleton; | |
import javax.ws.rs.GET; | |
import javax.ws.rs.Path; | |
import com.google.inject.AbstractModule; | |
import com.google.inject.Provides; | |
import com.google.inject.util.Modules; | |
import com.netflix.governator.InjectorBuilder; | |
import com.netflix.governator.LifecycleInjector; | |
import com.netflix.governator.ShutdownHookModule; | |
import com.netflix.governator.guice.jersey.GovernatorJerseySupportModule; | |
import com.netflix.governator.guice.jersey.GovernatorServletContainer; | |
import com.netflix.governator.guice.jetty.DefaultJettyConfig; | |
import com.netflix.governator.guice.jetty.JettyConfig; | |
import com.netflix.governator.guice.jetty.JettyModule; | |
import com.netflix.governator.providers.Advises; | |
import com.sun.jersey.api.core.DefaultResourceConfig; | |
import com.sun.jersey.api.core.ResourceConfig; | |
import com.sun.jersey.guice.JerseyServletModule; | |
public class JerseyMain { | |
@Path("/") | |
@Singleton | |
public static class SimpleResource { | |
public SimpleResource() {} | |
@GET | |
public String work() { | |
return "It Works"; | |
} | |
} | |
public static void main(String[] args) { | |
LifecycleInjector injector = InjectorBuilder | |
.fromModules( | |
new ShutdownHookModule(), | |
Modules.override(new JettyModule()) | |
.with(new AbstractModule() { | |
protected void configure() {} | |
@Provides | |
JettyConfig getConfig() { | |
return new DefaultJettyConfig().setPort(9090); | |
} | |
}), | |
new GovernatorJerseySupportModule(), | |
new JerseyServletModule() { | |
@Override | |
protected void configureServlets() { | |
serve("/*").with(GovernatorServletContainer.class); | |
} | |
@Advises | |
@Singleton | |
@Named("governator") | |
UnaryOperator<DefaultResourceConfig> getResourceConfig() { | |
return config -> { | |
Map<String, Object> props = config.getProperties(); | |
props.put(ResourceConfig.FEATURE_DISABLE_WADL, "false"); | |
config.getClasses().add(SimpleResource.class); | |
return config; | |
}; | |
} | |
} | |
).createInjector(); | |
System.out.println(injector); | |
} | |
} |
So here we have the following. We have a simple REST resource called SimpleResource which will take HTTP request on "/" address. Them we just have to configure Governator / Guice bindings and that's it.
We need to add the ShutdownHookModule in order to have a shutdown port for our server. I'm also overriding the JettyModule in order to change the server port to 9090. Them we need to add the Governator support for Jersey with GovernatorJerseySupportModule. Where we configure the PREFIX of all REST resource, in this case, will be "/*". We also are binding all REST resource with getResourceConfig. That's it we have a working service with we can run with $ ./gradle run or just run as the main class in eclipse for instance.
We need to add the ShutdownHookModule in order to have a shutdown port for our server. I'm also overriding the JettyModule in order to change the server port to 9090. Them we need to add the Governator support for Jersey with GovernatorJerseySupportModule. Where we configure the PREFIX of all REST resource, in this case, will be "/*". We also are binding all REST resource with getResourceConfig. That's it we have a working service with we can run with $ ./gradle run or just run as the main class in eclipse for instance.
Cheers,
Diego Pacheco