【问题标题】:Transforming a java object into a GraphQL object in order to return a response将 java 对象转换为 GraphQL 对象以返回响应
【发布时间】:2017-03-03 14:23:17
【问题描述】:

我在一个项目中使用 GraphQL Java 库,并试图在自定义 DataFetcher 中返回所需的结果。我究竟如何构造响应对象?据我所知,我不希望只以格式编写响应字符串。应该有更好的方法来为请求的字段分配值。

public Object get(DataFetchingEnvironment environment) {
    Integer id = environment.getArgument("id");
    //Process information and get results

    //What should the return object be?                             
    return result;
}

【问题讨论】:

  • 欢迎来到 Stack Overflow!请注意,您的问题非常简单。请参阅how to ask,以便其他用户可以更好地帮助您。祝你好运!

标签: java graphql graphql-java


【解决方案1】:

get() 的返回值应该是评估该特定操作的结果的对象。

例如,给定:

  private static GraphQLFieldDefinition allTodoes=
    GraphQLFieldDefinition
      .newFieldDefinition()
      .name("allTodoes")
      .type(new GraphQLList(todo))
      .argument(skip)
      .argument(take)
      .dataFetcher(fetcher)
      .build();

那么fetcher 需要返回满足GraphQLObjectTypetodo 的契约的对象的List

就我而言,我正在复制 this schema,因此我可以返回 ArrayListToDo 对象:

  private static class ToDo {
    public int id;
    public String text;
    public boolean complete;

    ToDo(int id, String text, boolean complete) {
      this.id=id;
      this.text=text;
      this.complete=complete;
    }
  }

这是整个架构,Java 风格:

/***
 Copyright (c) 2016 CommonsWare, LLC

 Licensed under the Apache License, Version 2.0 (the "License"); you may
 not use this file except in compliance with the License. You may obtain
 a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

package com.commonsware.agql.client.local;

import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import graphql.Scalars;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import graphql.schema.GraphQLArgument;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLList;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;

// schema inspired by https://gist.github.com/gsans/d857b0951077bdbbabd968e0431d97fe

public class TestSchema {
  private static class ToDo {
    public int id;
    public String text;
    public boolean complete;

    ToDo(int id, String text, boolean complete) {
      this.id=id;
      this.text=text;
      this.complete=complete;
    }
  }

  private static ArrayList<ToDo> TODOES=new ArrayList<>();

  static {
    TODOES.add(new ToDo(123, "get this sample working", false));
    TODOES.add(new ToDo(4567, "add more test cases", false));
    TODOES.add(new ToDo(89012, "add more documentation", false));
    TODOES.add(new ToDo(345678, "add more todoes", false));
  }

  private static GraphQLFieldDefinition id=
    GraphQLFieldDefinition
      .newFieldDefinition()
      .name("id")
      .description("unique identifier")
      .type(Scalars.GraphQLInt)
      .build();

  private static GraphQLFieldDefinition text=
    GraphQLFieldDefinition
      .newFieldDefinition()
      .name("text")
      .description("what is to be done")
      .type(Scalars.GraphQLString)
      .build();

  private static GraphQLFieldDefinition complete=
    GraphQLFieldDefinition
      .newFieldDefinition()
      .name("complete")
      .description("are we done yet?")
      .type(Scalars.GraphQLBoolean)
      .build();

  private static GraphQLObjectType todo=
    GraphQLObjectType.newObject()
      .name("Todo")
      .description("Something to be done")
      .field(id)
      .field(text)
      .field(complete)
      .build();

  private static GraphQLArgument skip=
    GraphQLArgument
      .newArgument()
      .name("skip")
      .description("return starting with this index")
      .type(Scalars.GraphQLInt)
      .build();

  private static GraphQLArgument take=
    GraphQLArgument
      .newArgument()
      .name("take")
      .description("return this number of todoes")
      .type(Scalars.GraphQLInt)
      .build();

  private static DataFetcher fetcher=new DataFetcher() {
    @Override
    public Object get(DataFetchingEnvironment env) {
      int startIndex=0;
      int endIndex=TODOES.size()-1;
      List<ToDo> result=null;

      try {
        if (env.containsArgument("skip")) {
          Integer skip=env.getArgument("skip");

          if (skip!=null) {
            startIndex=skip.intValue();
          }
        }

        if (env.containsArgument("take")) {
          Integer take=env.getArgument("take");

          if (take!=null) {
            endIndex=startIndex+take;
          }
        }

        result=TODOES.subList(startIndex, endIndex);
      }
      catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Exception processing request", e);
        // um, how do I get this error into result?
      }

      return(result);
    }
  };

  private static GraphQLFieldDefinition allTodoes=
    GraphQLFieldDefinition
      .newFieldDefinition()
      .name("allTodoes")
      .type(new GraphQLList(todo))
      .argument(skip)
      .argument(take)
      .dataFetcher(fetcher)
      .build();

  private static GraphQLObjectType rootQuery=
    GraphQLObjectType
      .newObject()
      .name("rootQuery")
      .field(allTodoes)
      .build();

  public static GraphQLSchema schema=
    GraphQLSchema.newSchema().query(rootQuery).build();
}

DataFetcher 的默认设置是使用 getter 或 public 字段来解析值,尽管他们的库中有选项可以执行其他 IIRC。

正如您从一条评论中看到的那样,我还没有弄清楚如何处理错误,尽管我确信有一个选项。

【讨论】:

  • 我在为 android 集成 apollo 客户端时遇到以下错误。你能帮忙吗? MyQuery$Variables 注解 [] 需要在 com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:50) 注册显式 JsonAdapter
  • @Mr.India:对不起,我不知道。我建议您提出一个单独的 Stack Overflow 问题,您可以在其中提供minimal reproducible example
  • 我添加了一个单独的问题 [stackoverflow.com/questions/52704388/…
猜你喜欢
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 1970-01-01
相关资源
最近更新 更多