ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GraphQL:拼接Stitching

2022-02-01 16:33:51  阅读:190  来源: 互联网

标签:stuNo Stitching Grade 拼接 GraphQL Student new using public


  GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

                                   ——出自 https://graphql.cn

  数据是有关系的,可以利用HotChocolate.Stitching功能,把业务逻辑相关联的实体数据,从后台的两个服务中关联起来,这有点api网关的组合功能,可以把前端的一次请求,分解成后端的多次请求,并把数据组合后返回回去。

  下面有这样一个例子:有个学生服务,有两个api,一个是查询全部学生,一个是按学号查询学生;另一个是成绩服务,有两个api,一个是按学号查询这个学生的全部成绩,一个是按id查询成绩。现在可以在学生实体中组合成绩,也可以在成绩实体中组合学生,这是因为学生和成绩是一个一对多的关系。

下面来看实例:

学生服务:GraphQLDemo03_Students

引入NuGet

HotChocolate.AspNetCore

HotChocolate.Data

 

Starup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;


namespace GraphQLDemo03_Students
{
    public class Startup
    {     
        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddSingleton<IStudentRepository, StudentRepository>()
                .AddGraphQLServer()
                .AddQueryType<Query>()             
                ;
        }
         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGraphQL();
            });
        }
    }
}

Query.cs

using HotChocolate;
using System.Collections.Generic;

namespace GraphQLDemo03_Students
{
    public class Query
    {  
        public IEnumerable<Student> GetStudents([Service] IStudentRepository studentRepository)
        {
            return studentRepository.GetStudents();
        }

        public Student GetStudent(string stuNo, [Service] IStudentRepository studentRepository)
        {
            return studentRepository.GetStudent(stuNo);
        }
    }
}

StudentRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace GraphQLDemo03_Students
{

    public interface IStudentRepository
    {
        IEnumerable<Student> GetStudents();
        Student GetStudent(string stuNo);
    }
    public class StudentRepository : IStudentRepository
    {
        public IEnumerable<Student> GetStudents()
        {
            var students = new List<Student>() {
                new Student("S0001","小张",20,true),
                new Student("S0002","小李",19,false),
            };
            return students;
        }
        public Student GetStudent(string stuNo)
        {
            var students = new List<Student>() {
                new Student("S0001","小张",20,true),
                new Student("S0002","小李",19,false),
            };
            return students.SingleOrDefault(s => s.StuNo == stuNo);
        }
    }

    public record Student(string StuNo, string Name, int Age, bool Sex);
}

成绩服务:GraphQLDemo03_Grades

 

引入NuGet包

HotChocolate.AspNetCore

HotChocolate.Data

 

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace GraphQLDemo03_Grades
{
    public class Startup
    {

        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddSingleton<IGradeRepository, GradeRepository>() 
                .AddGraphQLServer()  
                .AddQueryType<Query>()
                ;
        }    
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGraphQL();
            });
        }
    }
}

Query.cs

using HotChocolate;
using System.Collections.Generic;

namespace GraphQLDemo03_Grades
{  
    public class Query
    {
        public IEnumerable<Grade> GetGrades([Service] IGradeRepository gradeRepository, string stuNo)
        {
            return gradeRepository.GetGrades(stuNo);
        }

        public Grade GetGrade([Service] IGradeRepository gradeRepository, int id)
        {
            return gradeRepository.GetGrade(id);
        }
    }
}

GradeRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace GraphQLDemo03_Grades
{
    public interface IGradeRepository
    {
        IEnumerable<Grade> GetGrades(string stuNo);
        Grade GetGrade(int id);
    }

    public class GradeRepository : IGradeRepository
    {

        public IEnumerable<Grade> GetGrades(string stuNo)
        {
            var grades = new List<Grade>(){
                new Grade(1,"S0001",100,"语文"),
                new Grade(2,"S0001",99,"数学"),
                new Grade(3,"S0002",98,"语文"),
                new Grade(4,"S0002",97,"数学")
            };
            return grades.Where(s => s.stuNo == stuNo);
        }

        public Grade GetGrade(int id)
        {
            var grades = new List<Grade>(){
                new Grade(1,"S0001",100,"语文"),
                new Grade(2,"S0001",99,"数学"),
                new Grade(3,"S0002",98,"语文"),
                new Grade(4,"S0002",97,"数学")
            };
            return grades.SingleOrDefault(s => s.ID == id);
        }
    }
    public record Grade(int ID, string stuNo, float score, string subject);
}

最重要的是组合服务,即网关服务:GraphoQLDemo03_gateway

引入NuGet包

HotChocolate.AspNetCore

HotChocolate.Data

HotChocolate.Stitching

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;


namespace GraphQLDemo03_gateway
{
    public class Startup
    {
        const string Students = "students";
        const string Grades = "grades";

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpClient(Students, c => c.BaseAddress = new Uri("http://localhost:7000/graphql"));
            services.AddHttpClient(Grades, c => c.BaseAddress = new Uri("http://localhost:9000/graphql"));
            services
              .AddGraphQLServer()
              .AddRemoteSchema(Students, ignoreRootTypes: true)
              .AddRemoteSchema(Grades, ignoreRootTypes: true)
              .AddTypeExtensionsFromString("type Query { }")
              .AddTypeExtensionsFromFile("StudentStitching.graphql")
              .AddTypeExtensionsFromFile("GradeStitching.graphql")
              .AddTypeExtensionsFromFile("StudentExtendStitching.graphql")
              .AddTypeExtensionsFromFile("GradeExtendStitching.graphql")
              ;
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGraphQL();
            });
        }
    }
}

学生的Query类型

extend type Query{
  getonestudent(stuNo:String): Student @delegate(schema: "students", path:"student(stuNo:$arguments:stuNo)")
  getstudents: [Student] @delegate(schema: "students", path:"students")
}

学生Student上扩展的属性grades集合

extend type Student{
  grades: [Grade] @delegate(schema: "grades", path:"grades(stuNo: $fields:stuNo)")
}

成绩的Query类型

extend type Query{
   getGrades(stuNo:String): [Grade] @delegate(schema: "grades", path:"grades(stuNo:$arguments:stuNo)")
   getGrade(id:Int!): Grade @delegate(schema: "grades", path:"grade(id:$arguments:id)") 
}

成绩实体上扩展的学生student实体属性

extend type Grade{
  student: Student @delegate(schema: "students", path:"student(stuNo: $fields:stuNo)")
}

网关项目中通过AddHttpClient把子服务地址添加进来,再通过AddRemoteSchema把子项的架构引入进来,通过AddTypeExtensionsFromFile添加.graphql定义文件,实现类型的定义和拼接,使应用达到灵活性。

 

  想要更快更方便的了解相关知识,可以关注微信公众号   

 

 

标签:stuNo,Stitching,Grade,拼接,GraphQL,Student,new,using,public
来源: https://www.cnblogs.com/ljknlb/p/15859187.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有