I've spent some time trying to create a RESTful API with Jersey, Grizzly, Guice and Hibernate, and I'm having a very difficult time wrapping my head around how to wire everything together. This is what I've been able to figure out on my own.
I have a working DAO that implements a simple interface. I'm using Guice to inject here. I used this post as a reference.
public class ProjectDAO implements ProjectDAOGeneric { private final Provider<EntityManager> entityManagerProvider; @Inject public ProjectDAO(Provider<EntityManager> entityManagerProvider) { this.entityManagerProvider = entityManagerProvider; } @Transactional public void insert(Project project) { entityManagerProvider.get().persist(project); } // (...)
I created a very simple CRUD API with Jersey. I used this course I found on PluralSight for help.
@Path("/project") public class ProjectResource { private final ProjectDAOGeneric projectDAO; @Inject public ProjectResource(ProjectDAOGeneric projectDAO) { this.projectDAO = projectDAO; } @GET @Produces(MediaType.APPLICATION_JSON) public List<Project> getProjects() { return projectDAO.findAll(); } // (...)
From what I understand, I have to bridge Guice and HK2 so that both of them work together. I have something like this.
public class HK2toGuiceModule extends AbstractBinder { private Injector guiceInjector; public HK2toGuiceModule(Injector guiceInjector) { this.guiceInjector = guiceInjector; } @Override protected void configure() { bindFactory(new ServiceFactory<ProjectService>(guiceInjector, ProjectService.class)).to(ProjectService.class); } private static class ServiceFactory<T> implements Factory<T> { private final Injector guiceInjector; private final Class<T> serviceClass; public ServiceFactory(Injector guiceInjector, Class<T> serviceClass) { this.guiceInjector = guiceInjector; this.serviceClass = serviceClass; } @Override public T provide() { return guiceInjector.getInstance(serviceClass); } @Override public void dispose(T versionResource) { } }
After that, I can create a simple Guice Module to bind the
ProjectDAO
interface to its implementation.public class GuiceModule extends AbstractModule { @Override protected void configure() { bind(ProjectDAOGeneric.class).to(ProjectDAO.class); } }
- I imagine that we would then need to create a
ResourceConfig
to initialize Grizzly, also taking the Guice bridge into consideration. I have something like this.
@ApplicationPath("/")
public class Config extends ResourceConfig {
@Inject
public Config(ServiceLocator serviceLocator) {
packages("com.myproject");
Injector injector = Guice.createInjector(new GuiceModule());
initGuiceIntoHK2Bridge(serviceLocator, injector);
}
private void initGuiceIntoHK2Bridge(ServiceLocator serviceLocator, Injector injector) {
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(injector);
}
}
- I figure that the last step would be to use that
ResourceConfig
in order to initialize the GrizzlyHttpServer
.
public class Main {
public static final String BASE_URI = "http://localhost:8080/";
public static HttpServer startServer() {
final ResourceConfig config = new ResourceConfig().packages("com.myproject");
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), config);
}
public static void main(String[] args) throws InterruptedException, IOException {
// (...)
Now, I can't figure out how to do this. The only code I have here is the one that Grizzly provides by default. I'm not sure how to use the custom ResourceConfig
I created.
Most of what I found online was +5 years old, and the most relevant post on StackOverflow asking about this topic is 12 years old at this point. So I figured that either Google is not being very helpful or I'm missing something. I can't seem to figure it out on my own, and I definitely haven't been able to find any up-to-date resources about it.
With all this, I have two simple questions:
- Does my current approach even make sense?
- If it does, how can I connect everything together? What am I missing?
Thanks a lot