GVKun编程网logo

休息 – OData与GraphQL GraphQL比较OData有什么优势?

15

针对休息–OData与GraphQLGraphQL比较OData有什么优势?这个问题,本篇文章进行了详细的解答,同时本文还将给你拓展ava.lang.IllegalStateException:com

针对休息 – OData与GraphQL GraphQL比较OData有什么优势?这个问题,本篇文章进行了详细的解答,同时本文还将给你拓展ava.lang.IllegalStateException:com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration.graphQLSchemaProvider、DataLoader GraphQL 返回错误数据的问题、GraphQL ---02 GraphQL和C#结合的实战项目、graphql cli 开发graphql api flow等相关知识,希望可以帮助到你。

本文目录一览:

休息 – OData与GraphQL GraphQL比较OData有什么优势?

休息 – OData与GraphQL GraphQL比较OData有什么优势?

GraphQL比较OData有什么优势?
在Graphata中有什么可能在OData中是不可能的或困难的?

解决方法

What is possible in GraphQL which is not possible or difficult in
Data?

引起我关注的一个方面是Martijn Walraven在他的blog年的一个声明。

Amazingly,Facebook’s GraphQL endpoint still supports 4-year old
shipped versions of their iOS and Android apps!

单个端点支持多个版本而不依赖于版本的能力是至少有趣的。

ava.lang.IllegalStateException:com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration.graphQLSchemaProvider

ava.lang.IllegalStateException:com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration.graphQLSchemaProvider

如何解决ava.lang.IllegalStateException:com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration.graphQLSchemaProvider?

我在启动与 graphql 相关的 Spring Boot 应用程序时遇到异常。我是 graphql 的新手并且已经实现了一个示例,并且在尝试测试和启动服务器时出现以下错误。我很困惑,因为我已经在我的 gradle 中实现了所有内容,包括依赖项,但仍然看到这个问题并且不确定是什么原因造成的?

private final GraphQL graphQL;

private final GraphQLValidator graphQLValidator;



@Autowired
public GraphQLServiceImpl(GraphQLProviderResolver graphQLProviderResolver,GraphQLValidator graphQLValidator) {


    SchemaParserBuilder schemaParserBuilder = SchemaParser.newParser().scalars(new GraphQLDate()).file("myschema.graphql").
            resolvers(graphQLProviderResolver);
    SchemaParser schemaParser = schemaParserBuilder.build();

    GraphQLSchema schema = schemaParser.makeExecutableSchema();

    GraphQL.Builder graphQLBuilder = GraphQL.newGraphQL(schema);


    this.graphQL = graphQLBuilder.build();
    this.graphQLValidator = graphQLValidator;

}

   //BELOW HOW I EXECUTE THE QUERY FROM THE SCHEMA (THIS IS IN ANOTHER METHOD)
    ExecutionInput executionInput = new ExecutionInput(graphQLRequest.getQuery(),graphQLRequest.getoperationName(),null,graphQLRequest.getvariablesMap());

    ExecutionResult result = graphQL.execute(executionInput);

//graphql GRADLE DEPENDENCY
compile (''com.graphql-java:graphql-spring-boot-starter:5.0.2'')
compile (''com.graphql-java:graphql-java-tools:5.2.4'')    

错误 失败","logger_name":"org.springframework.boot.SpringApplication","thread_name":"main","level":"ERROR","level_value":40000,"stack_trace":"java.lang.IllegalStateException: com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration.graphQLSchemaProvider 上的错误处理条件\n\tat org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:64)\n\tat org.springframework.context .annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:102)\n\tat org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitionsForBeanMethod(ConfigurationClassBeanDeFinitionReader.java:178)\n\tat org.springframework.java:102 (ConfigurationClassBeanDeFinitionReader.java:140)\n\tat org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitions(ConfigurationClassBeanDeFinitionReader.java:116)\n\tat o rg.springframework.context.annotation.ConfigurationClasspostProcessor.processConfigBeanDeFinitions(ConfigurationClasspostProcessor.java:333)\n\tat org.springframework.context.annotation.ConfigurationClasspostProcessor.postProcessBeanDeFinitionRegistry(ConfigurationClasspostProcessor.java:243)\n\tat org.springframework support.PostProcessorRegistrationDelegate.invokeBeanDeFinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273)\n\tat org.springframework.context.support.PostProcessorRegistrationDelegate.invokebeanfactoryPostProcessors(PostProcessorRegistrationDelegate.java:98)\n\ProcessworkAbc AbstractApplicationContext.java:678)\n\tat org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:520)\n\tat org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebA pplicationCo ntext.java:118)\n\tat org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)\n\tat org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:307)\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)\n\tat org.springframework.boot.SpringApplication.run( SpringApplication.java:1180)\n\tat com.mycom.link.app.Application.main(Application.java:42)\nCaused by: java.lang.IllegalArgumentException: @ConditionalOnMissingBean 注解必须至少指定一个 bean(类型、名称或注释)\n\tat org.springframework.util.Assert.isTrue(Assert.java:68)\n\tat org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.validate(OnBeanCondition.java:279) \n\tat org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.(OnBeanCondition.java:275)\n\tat org.springframework.boot.autoconfigure.condit ion.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:111)\n\tat org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)\n\t... 17个常用帧省略

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

DataLoader GraphQL 返回错误数据的问题

DataLoader GraphQL 返回错误数据的问题

如何解决DataLoader GraphQL 返回错误数据的问题?

我使用带有 GraphQL 的节点开发了一个 API,当我添加 DataLoaders 时,解析器开始返回错误的数据,比如我传递了 4 个 Id [3,3,1,2],批处理函数在数据库中查找并返回有序的[1,2,3] 当返回到解析器时,第一个 id 为 3 的对象接收到 id 为 1 的响应。

Project Packages versions ->
    "DataLoader": "1.3.0","express": "^4.17.1","express-graphql": "^0.11.0","graphql": "^15.3.0","graphql-fields": "^2.0.3","graphql-tools": "^6.2.4",

我也尝试使用最新版本的数据加载器,但没有用

关注我的代码。

Resolver ->

Address: {
        idCity: (parent,args,{ db,DataLoaders: { cityLoader } }: { db: DbConnection,DataLoaders: DataLoaders },info: GraphQLResolveInfo) => {
            return cityLoader.load({ info,key: parent.get(''idCity'') })
                .catch(handleError);
        }
    },
Data Loader Factory ->

cityLoader: new DataLoader<DataLoaderParam<number>,CityInstance>(
                (params: DataLoaderParam<number>[]) => CityLoader.batchCities(this.db.City,params,this.requestedFields),{
                    cacheKeyFn: (param: DataLoaderParam<number[]>) => param.key
                }
            ),
DataLoaderParam ->

export interface DataLoaderParam<T> {
    key: T;
    info: GraphQLResolveInfo;
}
City Loader ->

export class CityLoader {
    static async batchCities(City: CityModel,params: DataLoaderParam<number>[],requestedFields: RequestedFields) {
        const ids: number[] = params.map(item => item.key);

        return City["findAll"]({
            where: { id: { $in: ids } },attributes: requestedFields.getFields(params[0].info,{ keep: [''id''],exclude: [] })
        });
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

GraphQL ---02 GraphQL和C#结合的实战项目

GraphQL ---02 GraphQL和C#结合的实战项目

本文章是介绍和记录如何创建GraphQL项目,以及如何使用GraphQL进行数据的相关操作。项目参照GraphQL .Net 的官方文档进行实践

一、项目结构:

  为了更好的和原有的项目结合在一起,尽可能减少对原项目的修改。我对项目结构做了如下分层。

二、项目结构分层说明

  Contracts层: 项目的接口层,重点存放项目的一些接口。和原项目的分层结构的Contracts一致

  Entities层: 实体模型层,存放实体模型。与原有项目的分层结构Entites层一致

  GraphQLDemo: 是使用Console控制台应用程序对GraphQL的调用实例

  GraphQLs: 使用GraphQL 的模型定义和查询、变更等操作的定义

  Services: 提供服务的具体实现层,和原有项目分层中的Services 层一致

  Tests: 使用Unit Test 测试调用GraphQL

在这里重点关注 标红的部分的介绍

三、GraphQLs项目介绍:

  GraphQLs重点是存储项目的GraphQL操作相关的内容

  1.在项目解决方案中,新建程序集,命名为GraphQLs

  2. 安装Graphql

NuGet 搜索 GraphQL

  3.创建GraphQL 的相关概念

  GraphQL有两种方式创建Schema,

    • 一种是使用Schema First,也就是使用GraphQL Schema Language创建Schema. 可以对比EntityFramework的DB First
    • 一种是使用Graph Type定义Schema,可以对比EntityFramework 的Code First

  在这里适用Code First定义数据模型,可以与原有的数据服务应用一起使用。可分为以下步骤:

  1)定义数据模型:

  假设原有的数据模型Book的结构是这样的:

public class User
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public string Gender { get; set; }
    }

  那么定义对应的GraphQL的数据模型可以是这样的:

public class UserType:ObjectGraphType<User>// 继承自ObjectGraphType,并传递范型User
    {
        public UserType()// 在构造函数中,对属性作影射
        {
            Name = "User";

            Field(x => x.Id);
            Field(x => x.Name);
            Field(x => x.Age);
            Field(x => x.Gender);
        }
    }

  2)定义操作模型

  GraphQL的操作分为: Query(Select), Mutation(Create,Update,Delete),Subscription(订阅)

  • 定义Query操作
public class Query : ObjectGraphType// 定义Query
    {
        private IWrapper wrapper = new Wrapper();
        IEnumerable<User> users = null;
        public Query()
        {
            Field<ListGraphType<UserType>>(//在构造函数中定义查询操作
                name: "users", //注意这个名字,后边查询的时候需要对应
                arguments: new QueryArguments //定义查询参数
                {
                    new QueryArgument<StringGraphType>
                    {
                        Name = "name",
                        Description = "The name for the user"
                    },
                    new QueryArgument<IntGraphType>
                    {
                        Name = "age",
                        Description = "The age for the user"
                    },
                    new QueryArgument<StringGraphType>
                    {
                        Name = "gender",
                        Description = "The gender for user"
                    }
                },
                resolve: context =>// 定义查询操作的执行
                {
                    var usercontext = context.UserContext;// 获取上下文,可在此作用户验证操作
                    users = wrapper.User.Find(u => true);
                    var name = context.GetArgument<string>("name");
                    users = users.Where(u => name == null || u.Name == name);
                    var age = context.GetArgument<int?>("age");
                    users = users.Where(u => age == null || u.Age == age);
                    var gender = context.GetArgument<string>("gender");
                    users = users.Where(u => gender == null || u.Gender == gender);
                    return users;
                });
    }
}
  • 定义Mutation操作
public class Mutation:ObjectGraphType
    {
        private IWrapper wrapper = new Wrapper();
        IEnumerable<User> users = null;
        public Mutation()
        {
            Field<UserType>(
                name: "createUser",
                arguments: new QueryArguments(
                    new QueryArgument<NonNullGraphType<UserInputType>>
                    {
                        Name = "user"
                    }
                ),
                resolve: context =>
                {
                    var user = context.GetArgument<User>("user");
                    return wrapper.User.Add(user);
                }
            );
        }
    }

  3. 定义GraphSchema

  定义GraphSchema就是定义Schema的Query、Mutation、Subscription操作

public class GraphSchema:Schema
    {
        public GraphSchema()
        {
            Query = new Query();
            Mutation = new Mutation();
        }
    }

  4. 附.

  为了检验查询、修改操作,这里定义一个GraphQLQuery来定义操作,并定义一个查询操作类

public class GraphQLQuery
    {
        public string OperationName { get; set; }
        public string NamedQuery { get; set; }
        public string Query { get; set; }

        public object UserContext { get; set; }
        public JObject Variables { get; set; }
    }
public class ActionExecute
    {
        private IDocumentExecuter executer;
        private IDocumentWriter writer;
        private ISchema schema;

        public ActionExecute()
        {
            executer = new DocumentExecuter();
            writer = new DocumentWriter();
            schema = new GraphSchema();
        }

        public async Task<ExecutionResult> ExecuteAction(GraphQLQuery query)
        {
            var result = await executer.ExecuteAsync(_ =>
            {
                _.Schema = schema;
                _.Query = query.Query;
                _.Inputs = query.Variables.ToInputs();// 查询变量的输入
                _.OperationName = query.OperationName;// 操作名称
                _.UserContext = query.UserContext;// 添加用户上下文对象
                _.ValidationRules = DocumentValidator.CoreRules(); // 添加自定义查询验证 逻辑 
                _.ExposeExceptions = true;// 是否追踪错误
                _.FieldMiddleware.Use<ErrorHandlerMiddleware>(); // 使用中间件
                _.EnableMetrics = true;// 是否使用查询度量

                _.ComplexityConfiguration = new ComplexityConfiguration // 防止恶意查询
                {
                    MaxComplexity = 12,
                    MaxDepth = 15 // 允许查询总最大嵌套数
                };
            });
            return result;
        }

        public async Task<string> Execute(GraphQLQuery query)
        {
            var result = await ExecuteAction(query).ConfigureAwait(false);

            var json = await writer.WriteToStringAsync(result);

            return json;
        }
    }

四、 测试和检验

  一切准备就绪,下边对创建的GraphQL进行测试

  1. 查询测试:
public class QueryTest
    {
        private ActionExecute execute = new ActionExecute();
        [Fact]
        public void TestMethod1()
        {
            Assert.True(1 == 1);
        }
        [Theory]
        [InlineData(16, "Male")]
        [InlineData(18, "FeMale")]
        public async void QueryUsers(int age, string gender)
        {
            var queryStr = @"{users(age:" + age + ",gender:" + "\"" + gender + "\"" + "){id name gender age}}";
            var result = await execute.ExecuteAction(new GraphQLQuery { Query = queryStr,UserContext= "Add Role" });
            var data = result.Data;
            Assert.Null(result.Errors?.Count);
        }
    }

  为了检验GraphQL的查询优越性,你可以修改一下queryStr=@"{users{id name gender age}}"; 或queryStr=@"{users{gender age}}";queryStr=@"{users{ name age}}";注意这里的@和{}只是C# 对字符串操作的一种方式。

  发现了什么?

  如果我们在前端(Web、微信小程序、手机APP),在web端,作为后台管理系统,我可能需要获取用户的所有信息,那么我可能需要使用queryStr=@"{users{id name gender age}}"。在微信小程序端,我只要根据用户的id查询用户名字就可以了,那么我只用变动查询语句:queryStr=@"{users(id){ name}}";

  意味着什么?

  意味着我们只需要提供一个API接口,该端口接受传递的查询字符串就可以了。所有的实体都可以只用这一个接口了。想查询什么,由前端决定了,再也不需要追着后端接口开发工程师要数据了。我想这样以来,前端和后端只需要一个接口沟通,会比REST API来的更方便了。

2.变更测试:

public class MutationTest
    {
        private ActionExecute execute = new ActionExecute();

        [Theory]
        [InlineData(16, "Test1")]
        [InlineData(18, "Test2")]
        public async void CreateUser(int age, string name)
        {
            var queryStr = @"{query: mutation ($user: UserInput!){createUser(user:$user){id name age}},variables:{user:{name: " + name + @",age:" + age + @"}}}";

            var query = new GraphQLQuery
            {
                Query = "mutation ($user: UserInput!){createUser(user:$user){id name age}}",
                Variables = JObject.Parse("{user:{\"name\": \"" + name + "\",\"age\":" + age + "}}")
            };
            var result = await execute.ExecuteAction(query);
            Assert.Null(result.Errors.Count);
        }
    }

  发现了什么?

  同样的。我们只需要传递查询的参数,传递对应的参数Variables 就能完成修改动作。同时,该变更和查询的操作字符串语句很像,只是多了一个mutation。

五、后续

  这篇文章只是介绍了使用控制台和UnitTest测试使用了GraphQL,后续会更新在Asp.Net Core MVC 中使用GraphQL,也可以学习杨旭的文章。很好的博主https://www.cnblogs.com/cgzl/p/9691323.html

 

graphql cli 开发graphql api flow

graphql cli 开发graphql api flow

 

作用

  • 代码生成

  • schema 处理

  • 脚手架应用创建

  • 项目管理

安装cli

npm install -g graphql-cli

初始化项目(使用.graphqlconfig管理)

以下为demo

  • demo 项目创建
graphql init
  • 添加数据操作(一般名称为database)

使用prisma cli

prisma init database
  • 添加database 项目
graphql add-project database
  • 修改配置

.graphqlconfig.yaml


 projects:
  demo:
    schemaPath: schema.graphql
    extensions:
      endpoints:
        default: ''http://localhost:4466''
  database:
    schemaPath: src/generated/prisma.graphql
    extensions:
      prisma: database/prisma.yml

  • 生成schema
graphql get-schema --project database

  • 代码生成

    • 生成typescript typings

    .graphqlconfig.yaml

    
    projects:
      demo:
        schemaPath: src/schema.graphql
        extensions:
          endpoints:
            default: ''http://localhost:4466''
          codegen: 
            generator: typegen
            language: typescript
            input: "{binding,prisma}/*.ts"
            output:
              typings: src/typings.ts
      database:
        schemaPath: src/generated/prisma.graphql
        extensions:
          prisma: database/prisma.yml
    
    graphql codegen
    
    
    • 生成type 定义

    修改配置

    projects:
    demo:
      schemaPath: src/schema.graphql
      extensions:
        endpoints:
          default: ''http://localhost:4466''
        codegen: 
          generator: prisma-binding
          language: typescript
          output:
            binding: src/prisma.ts
    database:
      schemaPath: src/generated/prisma.graphql
      extensions:
        prisma: database/prisma.yml
    
    graphql codegen
    
    
    • binding

    修改配置

    install binding:
    npm install -g graphql-binding
    
    projects:
    demo:
      schemaPath: src/schema.graphql
      extensions:
        endpoints:
          default: ''http://localhost:4466''
        codegen:
          - generator: graphql-binding
            language: typescript
            input: schema.js
            output:
              binding: mybinding.ts
    database:
      schemaPath: src/generated/prisma.graphql
      extensions:
        prisma: database/prisma.yml
    
    graphql codegen
 
 
 
 

今天关于休息 – OData与GraphQL GraphQL比较OData有什么优势?的介绍到此结束,谢谢您的阅读,有关ava.lang.IllegalStateException:com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration.graphQLSchemaProvider、DataLoader GraphQL 返回错误数据的问题、GraphQL ---02 GraphQL和C#结合的实战项目、graphql cli 开发graphql api flow等更多相关知识的信息可以在本站进行查询。

本文标签: