Description
I often get asked what to do with the servlet instance once it's created, as the servlet spec provides no programmatic way to register it. Some servlet containers do, when started programmatically (e.g. Jetty), but there's nothing portable. Spring also allows this, but if you already have Spring, creating a custom servlet is already a strange requirement, in the face of Spring MVC controllers etc.
So what people end up doing is what I did in the HowToGraphQL tutorial: subclass SimpleGraphQLServlet
, handle the entire setup in the constructor, and register that subclass with the container (using @WebServlet
or web.xml
) so the container can initialize it as usual. The problem with this is that all the setup steps need to be static and weirdly inlined as the call to super
needs to be the very first thing in the constructor. This is very unintuitive and cumbersome. Worse yet, until recently, there was no accessible non-deprecated constructor to call from the subclass, making the only obvious strategy obsolete.
So what I propose is to allow SimpleGraphQLServlet
to initialize its state in the usual Servlet#init(ServletConfig)
method instead of the constructor. This method exists in the spec exactly because the constructor is often a very inconvenient place to setup servlets.
E.g.
class SimpleGraphQLServlet {
@Override
public void init(ServletConfig config) {
Builder builder = getConfiguration();
if (builder != null) {
this.schemaProvider = builder.schemaProvider;
... // the same as the current constructor
}
}
//this is for the subclasses to optionally override
protected Builder getConfiguration() {
return null;
}
}
This would allow a very vanilla use of the servlet, compatible with any container with no surprises or workarounds needed:
@WebServlet(urlPatterns = "/graphql") //or via web.xml
public class GraphQLEndpoint extends SimpleGraphQLServlet {
@Override
protected Builder getConfiguration() {
return SimpleGraphQLServlet.builder(schema)
.withInstrumentation(..) //etc
}
}
This is just a quick example of what I mean. Instead of a Builder
, getConfiguration
could return some Configuration
object you could get e.g. by calling Builder#toConfiguration
instead of Builder#build
or whatever.
I could, of course, implement this if you'd want me to.