2

我正在尝试使用graphql-spqr将 GraphQLServlet 添加到我现有的网络服务中。

我已经添加了正确的注释,现在只需要设置 GraphQL 端点,这是我苦苦挣扎的地方。我发现的所有教程和谷歌结果都指的是类graphql.servlet.SimpleGraphQLServlet的不推荐使用的构造函数

我可以像这样创建一个 servlet 对象:

UserService userService = new UserService();
GraphQLSchema schema = new GraphQLSchemaGenerator()
                           .withOperationsFromSingleton(userService)
                           .generate();

graphql.servlet.GraphQLServlet servlet = new Builder(schema).build();

但我不知道是否以及如何注册 servlet 实例。搜索引擎要么误解了我的搜索,要么是空的。

我很感激任何指示。

4

2 回答 2

3

使用 Servlet 3+,您可以动态注册 servlet。这就是我出于完全相同的原因所做的(我不想使用已弃用的构造函数)。

@WebListener
public class GraphQLServletRegistrationServletContextListener implements ServletContextListener {

    private GraphQLSchema schema;

    public GraphQLServletRegistrationServletContextListener() {}

    @Inject
    public GraphQLServletRegistrationServletContextListener(final GraphQLSchema schema) {
        this.schema = schema;
    }

    @Override
    public void contextInitialized(final ServletContextEvent event) {
        final ServletRegistration.Dynamic dynamicGraphQLServlet
                = event.getServletContext().addServlet("GraphQLEndpoint", SimpleGraphQLServlet.create(schema));
        dynamicGraphQLServlet.addMapping("/graphql");
    }

    @Override
    public void contextDestroyed(final ServletContextEvent event) {}

}

我正在使用 CDI 注入 GraphQLSchema,但您可以忽略它并以您喜欢的任何方式手动构建它。

于 2018-03-08T14:41:39.290 回答
1

更新:从 graphql-java-servlet 6.x 开始,这个答案似乎已经过时了

除非您使用 Spring,否则实际上很难自己注册一个 servlet 实例(并且没有标准的方法来做到这一点),因为 Servlet 规范从未真正打算以这种方式使用它(容器应该负责实例化 servlet)。如果您使用的是Spring,那么无论如何都不需要创建 servlet。因此,使用SimpleGraphQLServlet往往不直观且不方便。

您可以采取的一种方法是对 进行子类化SimpleGraphQLServlet,并让容器按预期为您实例化它:

@WebServlet(urlPatterns = "/graphql")
public class GraphQLEndpoint extends SimpleGraphQLServlet {

    public GraphQLEndpoint() {
        super(schema());
    }

    private static GraphQLSchema schema() {
       UserService userService = new UserService();
       GraphQLSchema schema = new GraphQLSchemaGenerator()
                       .withOperationsFromSingleton(userService)
                       .generate();
       return schema;
    }
}

您也可以GraphQLEndpoint通过web.xml.

您会注意到您需要内联整个设置,因为调用必须super是构造函数调用的第一件事。这就是造成SimpleGraphQLServlet如此不便的原因。

另一种选择是创建您自己的 servlet。你需要立即做的事情真的不多。只需在其init方法中创建模式(不需要奇怪的内联设置),将其存储在实例字段中,然后接受doGetor中的查询doPost。当然还有处理错误、不同 URL 等的问题,这有点复杂,但你不需要马上学习基础知识。

您可能还想使用成熟的框架,例如 Spring MVC 或 Boot。您可以在graphql-spqr samples中找到一个示例。

于 2018-01-03T16:39:53.530 回答