集成开放平台标准化连接器之基于OAS3.0的API管理能力

bf2eccba4a29416d7a002fbbd2ccf983.png

5b4ceab4caf864fe1938ada6e8274fe3.png

源宝导读:随着企业信息化进程的逐步深入,互联网技术的发展和分布式系统应用的日益广泛,直接导致大量异构系统的存在,这些系统往往各自独立、封闭运行,相互之间不存在或很少存在数据的交互,由于这种应用分割,多个系统之间往往存在数据的冗余以及功能的重叠,各个系统之间信息传输、资源利用困难,形成所谓的“信息孤岛”。天际·集成开放平台,提供轻量化的API、事件、消息、数据集成能力,可以帮助您积木式、配置化的构建高可靠、高性能、低延迟的应用集成解决方案,实现企业云上云下、不同厂商、不同架构、不同协议的应用互联互通,并且平台还提供可视化的运维管理、实时的运行监控,保障集成可持续健康运行。当前文章主要阐述集成平台连接中心的API管理能力,把不同协议、不同厂商的服务转化成统一标准的Http协议服务,对外提供操作能力。对Http协议的描述,采用国际标准OAS 3.0规范。

一、OAS 3.0 初识

介绍

OAS 3.0即:OpenAPI Specification 3.0.*;OpenAPI 规范 为 REST API 定义了一种标准的、与编程语言无关的接口描述,它允许人类和计算机发现和理解服务的功能,而无需访问源代码、附加文档或检查网络流量. 当通过 OpenAPI 正确定义时,消费者可以使用最少的实现逻辑理解远程服务并与之交互。与接口描述为低级编程所做的类似,OpenAPI 规范消除了调用服务时的猜测。

发展史(来源wiki:https://en.wikipedia.org/wiki/OpenAPI_Specification)

Swagger开发始于 2010 年初,由在在线词典公司Wordnik工作的 Tony Tam 开始。[3] 2015 年 3 月,SmartBear Software从 Wordnik 的母公司 Reverb Technologies 那里收购了开源 Swagger API 规范。[4]

2015 年 11 月,SmartBear 宣布将在Linux 基金会的赞助下创建一个名为 OpenAPI Initiative 的新组织。其他创始成员公司包括3scale、Apigee、CapitalOne、谷歌、IBM、Intuit、微软、PayPal和 Restlet。[5] [6] [7] SmartBear 向新组捐赠了 Swagger 规范。该小组也在考虑RAML和API Blueprint。[8] [9]

2016 年 1 月 1 日,Swagger 规范更名为 OpenAPI 规范 (OAS),并移至新的GitHub 存储库。[10]

2016 年 9 月,API World 大会向 SmartBear 颁发了 API 基础设施奖,以表彰其在 Swagger 上的持续工作。[11]

2017 年 7 月,OpenAPI Initiative 发布了其规范的 3.0.0 版。[12] MuleSoft是替代RESTful API 建模语言(RAML)的主要贡献者,加入了 OAS 并开源了他们的 API 建模框架工具,该工具可以从 RAML 输入生成 OAS 文档。

变更版本

ef9cac95507b58ddbfe1eccabc399133.png

2.0 & 3.0 根节点属性示意图

参考:https://swagger.io/blog/news/whats-new-in-openapi-3-0

3acd39c7301e09bb701a62b9ca17869b.png节点说明 (参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#oasDocument)

84b48c37d352408987d175968c56d0ba.png

OpenAPI 根对象

# OpenAPI 规范版本号
openapi: 3.0.0# API 元数据信息
info:# 服务器连接信息
servers:# API 的分组标签
tags: # 对所提供的 API 有效的路径和操作
paths:# 一个包含多种纲要的元素,可重复使用组件
components:# 声明 API 使用的安全机制
security:# 附加文档
externalDocs:

Info 对象

# API 元数据信息
info:title:  xx开放平台接口文档                    # 应用的名称description: | 简短的描述信息,支持 markdown 语法。| 表示换行,< 表示忽略换行。version: "1.0.0"                            # API 文档的版本信息termsOfService: 'http://swagger.io/terms/'  # 指向服务条款的 URL 地址contact:                                    # 所开放的 API 的联系人信息name: API Support                           # 人或组织的名称url: http://www.example.com/support         # 指向联系人信息的 URL 地址email: apiteam@swagger.io                   # 人或组织的 email 地址license:                                    # 所开放的 API 的证书信息。name: Apache 2.0url: 'http://www.apache.org/licenses/LICENSE-2.0.html'

参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#infoObject

Server 对象

所有的 API 端点都是相对于基本 URL 的。例如,假设 https://api.example.com/v1 的基本 URL 中,/users 端点指的是 https://api.example.com/v1/users。

https://api.example.com/v1/users?role=admin&status=active
\ __________________ / \__/ \ ______________________ /服务器URL      端点路径        查询参数

Server 表示一个服务器的对象。这里通常填写测试服务器或者生产服务器的 IP 地址、端口版本号等信息(指定基本 URL)。

# 服务器连接信息
servers:- url: https://development.gigantic-server.com/v1description: 开发服务器- url: https://staging.gigantic-server.com/v1description: 测试服务器- url: https://api.gigantic-server.com/v1description: 生产服务器

参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#serverObject

Tag 对象

Tag 对象用于对 path 对象中的 API 进行分组,可以更美观的生成文档。

# API 的分组标签
tags: - name: petdescription: 与宠物相关的接口externalDocs:description: 外部文档url: 'http://swagger.io'- name: storedescription: 宠物商店- name: userdescription: 用户操作相关externalDocs:description: 外部文档url: 'http://swagger.io'

参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#tagObject

Path 对象

定义各个的端点和操作的相对路径。这里指定的路径会和 Server 对象 内指定的URL地址组成完整的URL地址,路径可以为空,这依赖于 ACL constraints 的设置。

参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#pathsObject

External Documentation 对象

允许引用外部资源来扩展文档

# 附加文档
externalDocs:description: Find out more about Swaggerurl: 'http://swagger.io'

参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#externalDocumentationObject

Components 对象

包含开放API规范固定的各种可重用组件。当没有被其他对象引用时,在这里定义定义的组件不会产生任何效果

# 一个包含多种纲要的元素,可重复使用组件
components:schemas:responses:parameters:examples:requestBodies:headers:securitySchemes:links:callbacks:
参考:componentsObject

详细节点说明参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#oasDocument

基于OAS 规范制作文档 

在开发团队中会产生很多基于Http协议的服务, 这些服务需要在团队中给测试或者接入方或者对外部表达这些服务接口,往往需要产生一个可以被查看的,或需要可以被调试的界面,这种Http具备要素是既定的,国际上多家大型企业参与并制定OAS的规范,对Http协议的各种属性进行规范表达。更多大家熟知的是不同语言提供的Swagger集成组件,在项目中集成Swagger扩展组件,Swagger会结合语言的一些规范,产生json文档,以及提供可被阅读以及调试的可视化界面,直接使用,非常便利,这样阅读对象就可以很好的阅读并调试对应Http服务的各种接口,市面上Swagger组件即为基于OpenApi规范产生的文档,继而提供基于文档规范的可视化界面,在项目中使用Swagger组件上面就可以看到对应的json文档地址,以及接口的描述

实用过程中,服务如何基于OpenAPI规范产生文档以及可视化界面

具体项目实现可参考:

  • net core: https://github.com/domaindrivendev/Swashbuckle.AspNetCore

  • java :https://github.com/swagger-api/swagger-core

  • php:https://github.com/zircote/swagger-php

项目集成组件之后呈现示例:

6441b199219e7fbd42466a51128a2f09.png

二:连接器基于OpenApi的管理能力

服务需要对外表达和描述一个接口,集成平台涉及接口管理的也需要进行表达和描述,其中接口中心和连接中心对接口的表达以及文档的存储都为基于OpenApi规范的json文档,下面描述连接中心模块,如下

示例图:

192c5443b49ce2e99cb106a088da1db9.png

连接器分两种类型:Http类型连接器,托管连接器

Http 类型连接器:保有现有Http的相关操作,处理授权以及接口表达,通过集成平台的网关进行转发

托管类型连接器:用户操作层面不变(Http协议),集成平台内部实现具体动作,构建连接器管道,网关请求的时候会识别当前连接器的类型,以及规范路由从而进入连接器的管道,实现对应连接器的托管实现

                             例如:数据库连接器,把这种非Http协议的连接器,对外转化成统一的Http协议接口,数据库连接器提供了两个接口-》查询和写入,用户调用只需要通过接口的形式,最终操作集成平台的连接器实现

9c54c1d17d2f114b640618238dd330f3.png

Http连接器接口示例:和托管连接器对外实现接口描述一致

82186311a86f8f2a4676b3b7946e5ec4.png

基于Http连接器,系统提供自发现&OpenApi 2.0,3.0规范文档的导入实现

背景

大多数用户存在很多这种Http协议的微服务,或者某个服务有很多接口, 用户本身也需要对接口进行表达,并提供使用方调用;现使用集成平台,如果手动添加,或者我们提供一种新的规则导入形式都会给用户带来不小的维护成本,基于种种考虑和用户的真实诉求,集成平台按照国际规范提供基于OAS规范的文档导入,可以给用户减少数据的维护操作,增加便利;下面介绍集成平台的实现逻辑。

1、自发现

用户在创建连接器的时候,系统会自动扫描连接下面的swagger页面,获取页面中对应的json文件地址,读取并解析,然后把每个Api拆分成单个OpenApi规范的json文档进行存储

示例:

0034fbe20e4e461eb3b718e0edf15775.png

2、导入功能

用户可以填写json文档地址,或者上传json文件,提交服务端,读取并解析,然后把每个大的json文档拆分成单个Path组成的OpenApi规范的json文档进行存储

示例:

b8e6a2e032398c46ef77ec4e797a4851.png

3、集成系统对API的描述呈现

新建或者自发现或者导入, 在系统存储中,每个Api是一个OpenApi 3.0规范的json文档,页面上面每个Api的详情,即为解析json做界面渲染

8a2ec240784658975a9793342994c6bf.png

组件实现基础介绍

集成平台后端技术主要为net core框架,作为OpenApi规范创始成员之一的微软,对Core框架提供了相对成熟的扩展组件

Microsoft.OpenApi -》提供基于OpenApi规范的构建能力等

Microsoft.OpenApi.Readers-》提供基于OpenApi规范json文档的读取转化能力,以及把对象转发成json字符串的能力等

源码:https://github.com/Microsoft/OpenAPI.NET

构建示例

var document = new OpenApiDocument{    Info = new OpenApiInfo    {        Version = "1.0.0",        Title = "Swagger Petstore (Simple)",    },    Servers = new List<OpenApiServer>    {        new OpenApiServer { Url = "http://petstore.swagger.io/api" }    },    Paths = new OpenApiPaths    {        ["/pets"] = new OpenApiPathItem        {            Operations = new Dictionary<OperationType, OpenApiOperation>            {                [OperationType.Get] = new OpenApiOperation                {                    Description = "Returns all pets from the system that the user has access to",                    Responses = new OpenApiResponses                    {                        ["200"] = new OpenApiResponse                        {                            Description = "OK"                        }                    }                }            }        }    }};br

集成平台连接中心Http连接导入功能

实现模式:系统中对接口的描述,每个接口都会有一个独立的文档描述,什么叫独立,独立是指一个OpenApi规范文档的最小粒度,一个Path一个文档

                  所以我们实现的时候,把一个大的文档,按照Path切割成若干的小文档,并对单条数据进行填充,转化成关系型的数据,例如一个接口会包含:请求类型,名称,请求路径等

流程示意图

709f986847d62d16bd12797c39d79db7.png

核心逻辑演示说明:主要分5步

1、通过地址或者文件读取内容成文本

using (var httpClient = _httpClientFactory.CreateClient())  {      string jsonStr = await httpClient.GetStringAsync(address);  }文件读取:using (StreamReader reader = new StreamReader(fileStream)) {      string jsonStr = await reader.ReadToEndAsync(); }br

2、通过微软提供的组件读取文本,转化成对象

OpenApiDocument openApiDocument= new OpenApiStringReader()     .Read(jsonStr, out diagnostic);//说明:diagnostic为OpenApiDiagnostic, 输出值为版本号:2.0或3.0 //     来源nuget库-》Microsoft.OpenApi.Readers          // OpenApiDocument  来源nuget库-》Microsoft.OpenApi// OpenApiStringReader 来源nuget库-》Microsoft.OpenApi.Readersbr

3、遍历文档的Path,构建粒度最小的OpenApi规范文档,一个Path对应一个文档

/// <summary>/// 拆分文档,并组装数据/// </summary>/// <param name="list">解析文档成结构化以及主要信息平铺的对象集合</param>/// <param name="openApiDocument">原始的大Document</param>/// <param name="connectionCode">连接编码</param>public static void ConverterSplit(List<ConnectionApiModel> list, OpenApiDocument openApiDocument, string connectionCode){  //校验文档的有效性  if (openApiDocument?.Paths == null || openApiDocument.Paths.Count < 1) return;  foreach (var item in openApiDocument.Paths)  {     //构建Document对象     var docmentEntity = OpenApiOperExtensions.InstantiationSimplified        (item.Value.Operations?.FirstOrDefault().Value?.Summary,            openApiDocument?.Info?.Version ?? INFO_VERSION,          item.Value.Operations?.FirstOrDefault().Value?.Description);     //增加单path     docmentEntity.AddPath(item);     //增加当前Path涉及的Components     docmentEntity.AddComponents(openApiDocument.Components,                                        item.Value);     //增加当前Path的Security     docmentEntity.AddSecuritySchemes(                      openApiDocument.Components?.SecuritySchemes);     //增加默认Schema - 非必须     docmentEntity.AddDefaultSchema();     //解析document对象为文本并添加list对象     Generate(docmentEntity, list, item, connectionCode);}br

构建Document说明

public static OpenApiDocument InstantiationSimplified(string title, string version, string description)        {            return new OpenApiDocument            {                Info = new OpenApiInfo                {                    Title = title,                    Version = version,                    Description = description                },                Paths = new OpenApiPaths(),                Components = new OpenApiComponents()            };        }br

添加Path说明

public static void AddPath(this OpenApiDocument openApiDocument, KeyValuePair<string, OpenApiPathItem> path)        {            ArgNullCheck(openApiDocument);            if (openApiDocument.Paths == null)            {                openApiDocument.Paths = new OpenApiPaths();            }            if (openApiDocument.Paths.ContainsKey(path.Key)) return;            openApiDocument.Paths.Add(path.Key, path.Value);        }br

增加SecuritySchemes说明

授权的SecuritySchemes为所有接口公用,拆分过程中,只需要每个最小粒度的文档包含即可。

增加Components

找出当前Path引用的Components,当前操作会稍显麻烦,在真实操作的时候单个Path的参数引用模型是可以是嵌套的模式,在获取当前Path的Ref引用(引用会在Components包含)需要递归操作。

4、组装Api数据,并把单条文档转化成json字符串,便于存入数据库

RequestPath = 解析当前Path的路由Swagger = 当前Path的规范文档(json)ConnectionCode = 连接器业务编码(用户侧填写)ApiName = 接口名称(解析Path的Summery属性得到)Description = 接口描述(解析Path的Description属性)HttpMethod = 请求类型(解析Path的请求类型)

5、入库

集成平台连接中心Http连接导出功能

导出即为导入逆向的操作, 把多个单Document,聚合成一个大的OpenApi规范的Document,进行导出

03e3ab35b2137b9731bde38bd99a4826.png

导出逻辑不做代码演示,和导入动作类似,需要建立新的Document,解析所有需要导出的接口数据,并把接口的规范文档(json存入)通过微软组件对象化,组装成一个总的Json文档,进行输出即可。

总结

导出的逻辑可以各自思考一下

本文章主要想对连接器的导入导出结合OAS规范文档做一些说明

希望大家对OAS规范文档有个初步认识,对集成平台连接器的导入和导出结合OAS规范文档的实现能得到一些收获

参考文章

https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md

https://en.wikipedia.org/wiki/OpenAPI_Specification

https://spec.openapis.org/oas/v3.0.3

https://swagger.io/specification/

https://github.com/Microsoft/OpenAPI.NET

------ END ------

作者简介

孙同学: 研发工程师,目前负责集成平台相关研发工作。

也许您还想看:

技术分享|Java SDK动态数据源和上下文机制

技术分享|NodeJS分布式链路追踪实现

更多明源云·天际开放平台场景案例与开发小知识,可以关注明源云天际开发者社区公众号:

【建模】文档服务提供高保真打印模式

明源云·天际硬核技术认可:获华为鲲鹏技术认证书

天际·开发者社区“重装发布”!

c299dd8821bdf656d966266515984c80.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

axure 组件_技巧分享 | Axure后台组件制作的全过程

点击上方蓝字&#xff0c;关注行设视觉黑马家族成员原创发布于行设视觉&#xff0c;转载请注明出处。作者 | 时光若刻http://www.woshipm.com/rp/2527010.html大家好&#xff0c;前一段时间我刚刚分享了一篇《打造高品质Axure组件库就是这么简单》&#xff0c;意在分享给大家一…

有没有测试人心里的软件,心理测评,认识自己的有效工具:(二)你做的可能是假的心理测试...

上一篇文章主要介绍了心理测评的基础知识&#xff0c;今天在上一篇的基础上&#xff0c;介绍下网上一些随处可见的心理测评&#xff0c;是如何的错误&#xff0c;以及怎么“迷惑”大家的&#xff1f;网上随便搜的一个阅读量超过10w的"心理"测试&#xff1a;测试他人会…

这相册一出手,哪个长辈搞不定?

1 这相册看着多喜庆看这花多美▼2 不会只有我一个人连最普通的都叠不好吧&#xff1f;▼3 真就史上最惨毕业生连毕业照都不配拥有吗&#xff1f;▼4 看起来经历了很严格的军训▼5 我闺蜜【偷】男票的钱给我买MAC air▼6 在台湾爸比和东北妈妈中间无缝切换▼7 先漱口、后…

医疗大数据:商业保险、移动医疗的崛起,正在形成闭环(二)

以下内容摘自华创证券分析师 吴晓雯、张伟光的《挖掘医疗大数据中的金矿》报告。 接上篇&#xff1a;医疗大数据&#xff1a;商业保险、移动医疗的崛起&#xff0c;正在形成闭环&#xff08;一&#xff09; 三、 商业保险、移动医疗等商业力量的崛起&#xff0c;加速医疗大数据…

WriteComponent,ReadComponent

WriteComponent,ReadComponent 代码 varForm1: TForm1; ms: TMemoryStream;implementation{$R *.dfm}procedureTForm1.Button1Click(Sender: TObject);varaBtn: TButton;beginaBtn :TButton.Create(Self); aBtn.Parent :Self; aBtn.Caption :Test; aBtn.Left :10; ms.WriteComp…

jquery 使用方法

jQuery是目前使用最广泛的javascript函数库。据统计&#xff0c;全世界排名前100万的网站&#xff0c;有46%使用jQuery&#xff0c;远远超过其他库。微软公司甚至把jQuery作为他们的官方库。对于网页开发者来说&#xff0c;学会jQuery是必要的。因为它让你了解业界最通用的技术…

bread是可数还是不可数_雅思官方语法教程之——这个名词到底可不可数?

名词是否可数&#xff0c;是非常隐形的扣分点。考生很可能意识不到自己犯错了&#xff0c;毕竟这是中文里不存在的语法点。这类语法点更应该重点备考。越练习&#xff0c;越熟悉&#xff0c;犯错扣分的几率也就越低。OK进入主题↓语法解释官方对可数和不可数名词的解释如下&…

google的api key调用次数是多少_Sprint Boot如何基于Redis发布订阅实现异步消息系统的同步调用?...

前言在很多互联网应用系统中&#xff0c;请求处理异步化是提升系统性能一种常用的手段&#xff0c;而基于消息系统的异步处理由于具备高可靠性、高吞吐量的特点&#xff0c;因而在并发请求量比较高的互联网系统中被广泛应用。与此同时&#xff0c;这种方案也带来了调用链路处理…

全球2%高智商天才必测脑力题!却只有1%的人,能在5分钟内全部做对!

▲ 点击查看说起娱乐圈最“变态”的养娃爸爸&#xff0c;妥妥非吴尊莫属&#xff01;上亿元的学区别墅、几十万学费1年的文莱国际幼儿园、一周7天辅导班、家教、每年1个儿童国际比赛、考证拿奖……1个吴尊绝对抵得上8个海淀妈。前段时间吴尊晒出neinei二年级毕业成绩单&#xf…

爬取三千条数据需要多久_存储-性能,IOPS,带宽,吞吐量,1TB数据需要多久写完...

让我们先看一下这三个概念&#xff1a;IOPS (Input/Output Per Second) 即每秒的输入输出量(或读写次数)&#xff0c;是衡量存储介质性能的主要指标之一。IOPS是指每秒钟系统能处理的读写请求数量。 吞吐量&#xff08;Throughput &#xff09;衡量的是存储介质的数据传输速率&…

TortoiseSVN客户端重新设置用户名和密码[转]

在第一次使用TortoiseSVN从服务器CheckOut的时候&#xff0c;会要求输入用户名和密码&#xff0c;这时输入框下面有个选项是保存认证信息&#xff0c;如果选了这个选项&#xff0c;那么以后就不用每次都输入一遍用户名密码了。 不过&#xff0c;如果后来在服务器端修改了用户名…

这就是你们有钱人炫富的新方式吗?

1 真正的1秒可爱喷雾▼2 你们父子俩的脚咋回事啊&#xff1f;▼3 咦&#xff1f;影子动了&#xff01;▼4 小姐姐&#xff0c;你这样就很过分了&#xff01;▼5 宝宝发现了一个新玩具▼6 这就是有钱人炫富的新方式吗&#xff1f;▼7 单身久了&#xff0c;看两片茶叶转圈…

Dapr + .NET 实战(五)Actor

什么是Actor模式Actors 为最低级别的“计算单元”以上解释来自官方文档&#xff0c;看起来“晦涩难懂”。大白话就是说Actors模式是一段需要单线程执行的代码块。实际开发中我们经常会有一些逻辑不能并发执行&#xff0c;我们常用的做法就是加锁&#xff0c;例如&#xff1a;lo…

打印机一直显示正在打印中_中国和桌面3D打印机正在引领3D打印市场

2020年11月4日&#xff0c;南极熊获悉&#xff0c;国外的市场研究公司CONTEXT最近发布了3D打印市场报告&#xff0c;“中国”和“桌面3D打印机”正引领全球的3D打印市场从COVID-19疫情中复苏。分析报告显示&#xff0c;在2020年第一季度至第二季度期间&#xff0c;中国国内工业…

python中的星号和乘号_Python 函数中参数前面一个和两个星号(**)的区别

Python是一种计算机程序设计语言。是一种面向对象的动态类型语言&#xff0c;最初被设计用于编写自动化 脚本( shell)&#xff0c;随着版本的不断更新和语言新功能的添加&#xff0c;越来越多被用于独立的、大型项目的开发。在 Python 的函数中经常能看到输入的参数前面有一个或…

sql重新注册服务器,sql server无法新建注册服务器怎么办?

SQL Server 不存在或访问被拒绝ConnectionOpen (Connect())这个"SQL Server 不存在或访问被拒绝"通常是最复杂的&#xff0c;错误发生的原因比较多&#xff0c;需要检查的方面也比较多。一般说来&#xff0c;有以下几种可能性&#xff1a;1、SQL Server名称或IP地址拼…

雨中的蚊子为啥不会被雨滴砸死?

全世界只有3.14 % 的人关注了爆炸吧知识在细雨中漫步是很浪漫的一件事&#xff0c;但作为蚊子&#xff0c;雨中飞行相当于天上掉汽车&#xff01;你有没有想过&#xff0c;它们是怎么活下来的&#xff1f;直到2015年&#xff0c;菠萝科学奖物理学奖颁给美国佐治亚理工学院胡立德…

.NET 6 迁移到 Minimal API

.NET 6 迁移到 Minimal APIIntro上次写了一篇 Minimal API Todo Sample&#xff0c;有些童鞋觉得 Minimal API 有些鸡肋&#xff0c;有一些功能的支持都不太好&#xff0c;但是其实 Host 之前支持的功能 Minimal API 大部分都是支持的&#xff0c;上次的 Todo Sample 完全没有使…

教你透彻了解红黑树

教你透彻了解红黑树 作者&#xff1a;July、saturnman 2010年12月29日本文参考&#xff1a;Google、算法导论、STL源码剖析、计算机程序设计艺术。本人声明&#xff1a;个人原创&#xff0c;转载请注明出处。推荐阅读&#xff1a;Left-Leaning Red-Black Trees, Dagstuhl Wor…

cass字体_不动产 准备工作 第一步: 管理CASS码

管理CASS码https://www.zhihu.com/video/1063850168960647168管理CASS码 功能概述&#xff1a;通过管理CASS码将不动产基础矢量数据分为房屋、房屋附属、其他设施三类&#xff0c;同时通过管理CASS码可以对建筑物面积计算规则进行自定义和统设、以及设置建筑物注记文本(和数据入…