前言

以前需要提供Web服务接口的时候,除了标准的WEBAPI形式,还考虑了OData、GraphQL等形式,虽然实现思路上有很大的区别,但对使用方来说,都是将查询的主动权让渡给了前端,让调用方能够更加自由地发挥或者符合自己要求的数据。其中,OData作为传统REST WEBAPI的拓展,对外还是WEBAPI的形式,为了照顾到和第三方对接的兼容性,我最终使用了OData作为首选技术。

OData在使用上方便性不言而喻,简直爱不释手,不过逐渐也发现一个问题:Mock不方便!前端常用的比如json-schema-faker无法识别OData的标记,返回的内容依旧是传统API返回的内容(无法输出@odata之类的内容)。

P.S. 最近还非常烦恼和OData一起使用EF Core时,由于有导航属性(Navigation Property),mock框架会循环引用导致Maximum call stack size exceeded的问题。一直没有找好办法,如果有朋友知道,还请不吝赐教。

于是和调用方的扯皮一直延续,最后还是先上线了后台暂时处理了这个问题。最近有一个想法浮到水面:反正mock是不可能mock了,调用方已经要恨死我了,就干脆点直接WebAPI形式也不要了,摊牌了。

GraphQL

GraphQL是Facebook推出的一项提供数据API的语言,和WEBAPI相比较,它有一些自己的特点,详细介绍可以看这里,最吸引我的地方,就是请求API可以一步到位,处理一些逻辑的时候,简单的一个API请求就可以得到所有的数据(当然使用OData的expand等查询也可以达到类似的效果),而且描述语言也比较简洁。这样调用方可以精确描述自己需要什么,接口返回不多不少刚刚好的数据,优雅!

关于GraphQL的介绍,可以查看其他文章,不是本文的重点。

体验

使用GraphQL,.NET支持的有很多库,比较流行的,有GraphQL.NET和HotChocolate,作为一个肥宅,我就选HotChocolate作为主要使用的库,直接使用nuget安装即可。

install-package HotChocolate.AspNetCore

新建一个新的ASP.NET CORE空项目,添加HotChocolate.AspNetCore的nuget包,然后定义以下数据结构

public class Class
{
public string Name { get; set; }
public Teacher Teacher{get;set;}
}
public class Student
{
public string Realname { get; set; } public Class Class{get;set;}
}
public class Teacher
{
public string Realname { get; set; }
public bool IsSupervisor{get;set;}
}

描述一个班级,教师和学生的关系,如果是REST API的话,一般需要三个接口表述三种不同的资源。GraphQL只有一个Endpoint,这个就比较简单了。

接下来定义暴露的接口:

using System.Collections.Generic;

using System.Linq;

namespace Demo
{
public class Query
{
private List<Student> GetStudents()
{
List<Student> students = new List<Student>();
students.Add(new Student
{
Realname = "ZHANGSAN",
Class = new Class
{
Name = "GAOSAN",
Teacher = new Teacher { Realname = "LISI", IsSupervisor = false }
}
});
students.Add(new Student
{
Realname = "ZHANGSAN2",
Class = new Class
{
Name = "GAOSAN1",
Teacher = new Teacher { Realname = "LISI", IsSupervisor = true }
}
});
return students;
}
public IEnumerable<Student> StudentInfo(string name)
{
if(string.IsNullOrWhiteSpace(name)) return GetStudents();
return GetStudents().Where(w=>w.Realname == name);
}
}
}

提供了一个StudentInfo可以对外接口。

public void ConfigureServices(IServiceCollection services)
{
services.AddGraphQLServer().AddQueryType<Query>();
} //在configure中
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQL();
});

然后然后直接F5运行,访问HotChocolate自带的分析器地址:http://localhost:5000/graphql/



直接查询即可得到结果,换一种查询条件:



可以发现,GraphQL返回的内容是可以由调用方进行定义的,你要啥它给啥,不用的字段你不写就不返回。很多时候,只要一次查询就能完成多次普通WebAPI请求才能达到的目标。(这个例子还不能表现出这个特点,有机会以后补充)。

补充

如果调用方不会GraphQL的话,不建议轻易上这个技术,因为他们来一句“这不是标准WEBAPI或者Webservice,我们调不了。”就把你噎死了。好多歹说就算终于上了,你还需要告诉清楚他们每一个接口的请求内容,这就纯粹给自己找事,体验太不好了。

最新文章

  1. VirtualBox上搭建Ubuntu开发环境
  2. iOS RSA加密解密及签名验证
  3. LinqToEntity模糊查询的方法选择
  4. NetBios 的结构体详解(网络控制块NCB)
  5. java中的内部类小结
  6. Direct2D开发:从资源加载位图
  7. android 定制自己的日志工具
  8. README.md
  9. TCP/IP——内外网IP+子网掩码作用+PING(网络总结)
  10. Arrays.sort源代码解析
  11. CSS定位属性Position详解
  12. SDP简要解析
  13. [译]Stairway to Integration Services Level 9 - Control Flow Task Errors
  14. pptv web前端面试题
  15. 为什么delphi控件前面都有t
  16. C#中枚举的使用
  17. cok-filter
  18. Winform MDI窗体切换不闪烁的解决办法(测试通过)
  19. 剑指Offer 55. 链表中环的入口结点 (链表)
  20. 《奔跑吧Ansible》

热门文章

  1. Cloudera Manager添加主机节点
  2. LeetCode383. 赎金信
  3. xray—学习笔记
  4. SAP中的密码输入框
  5. Redis 实战 —— 04. Redis 数据结构常用命令简介
  6. Java 给Word不同页面设置不同背景
  7. Linux进程内存用量分析之堆内存篇
  8. Transformation-Based Error-Driven Learning and Natural Language Processing: A Case Study in Part-of-Speech Tagging
  9. nginx http模块开发入门
  10. python 基础二-----数据类型和控制语句