webapi 多个版本的架构设计_webapi call another webapi - CSDN
精华内容
参与话题
  • WebAPI多版本管理

    千次阅读 2018-08-09 13:56:56
    原文地址:https://blog.csdn.net/Fanbin168/article/details/80683072

    原文地址:https://blog.csdn.net/Fanbin168/article/details/80683072

    什么是API 的多版本问题?

    Android 等App 存在着多版本客户端共存的问题:App 最新版已经升级到了5.0了,但是有的用户手机上还运行着4.8、3.9甚至2.2版本的App,由于早期没有内置升级机制、用户不会升级、用户拒绝升级等原因,造成这些旧版本App也在运行。

    开发新版本App的时候,要给接口增加新的功能或者修改以前接口的规范,会造成旧版本App无法使用,因此在一定情况下会“保留旧接口的运行、新功能用新接口”,这样就会存在多版本接口共存的问题。

    通常的做法是:旧版接口做一个代码分支,除了进行bug修改外,旧版本接口不再做改动;新接口代码继续演化升级。在客户端请求的时候带着要请求的接口版本号,在服务器端选择合适的版本代码进行处理。

    技术处理方法:
    1> (最推荐)不同版本用不同的域名:v1.api.rupeng.com、v2.api.rupeng.com、v3……;
    2> 在url、报文头等中带不同的版本信息,用Nginx等做反向代理服务器,然后将http://api.rupeng.com/api/v1/User/1http://api.rupeng.com/api/v2/User/1转到不同的服务器处理。
    3> 多个版本的Controller共处在一个项目中,然后使用[RoutePrefix]或者IHttpControllerSelector

    现在我们来看看多个版本的Controller共处在一个项目中这种情况下我们的如何处理

    处理方法1:
    通过个控制器和方法打RoutePrefix标签和Route标签的方式,根据路由规则,来选择哪个控制器
    例如:
    http://localhost:14483/api/v1/Person/1 这个URL地址的请求由PersonController控制来处理
    http://localhost:14483/api/v2/Person/1 这个URL地址的请求由PersonV2Controller控制来处理

    namespace WebApi.Controllers
    {
        [RoutePrefix("api/v1/Person")]
        public class PersonController : ApiController
        {
            [Route("{id}")]
            public string Get(int id)
            {
                return "我是旧版" + id;
            }
        }
        [RoutePrefix("api/v2/Person")]
        public class PersonV2Controller : ApiController
        {
            [Route("{id}")]
            public string Get(int id)
            {
                return "我是V2版" + id;
            }
        }
    }

    处理方法2(推荐):自定义IHttpControllerSelector
    第一步:根据版本号配置路由

    namespace WebApi
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // Web API 配置和服务
    
                // Web API 路由
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                //根据版本号来注册路由:第v1版本的请求地址:http://localhost:14483/api/v1/Person/Get
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApiv1",
                    routeTemplate: "api/v1/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                //根据版本号来注册路由:第v2版本的请求地址:http://localhost:14483/api/v2/Person/Get
                config.Routes.MapHttpRoute(
                    name: "DefaultApiv2",
                    routeTemplate: "api/v2/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                //将自定义的VersionControllerSelector注册到系统中
                config.Services.Replace(typeof(IHttpControllerSelector),new VersionControllerSelector(config));
            }
        }
    }

    第二步:创建一个VersionControllerSelector.cs类

    namespace WebApi.App_Start
    {
        public class VersionControllerSelector : DefaultHttpControllerSelector
        {
            private HttpConfiguration _config;
            IDictionary<string, HttpControllerDescriptor> controllers = null;//缓存用
            public VersionControllerSelector(HttpConfiguration config) : base(config)
            {
                _config = config;
            }
    
            //设计就是返回HttpControllerDesriptor的过程
            public override System.Web.Http.Controllers.HttpControllerDescriptor SelectController(HttpRequestMessage request)
            {
                //获取所有的controller键值集合
                if (controllers == null)
                {
                    GetControllerMapping();
                }
                //获取路由数据
                var routeData = request.GetRouteData();
                //从路由中获取当前controller的名称
                var controllerName = (string)routeData.Values["controller"];
                //从url中获取到版本号
                string verNum = Regex.Match(request.RequestUri.PathAndQuery, @"api/v(\d+)").Groups[1].Value;
                string key = controllerName + "v" + verNum;//获取Personv2
                if (controllers.ContainsKey(key))//获取HttpControllerDescriptor
                {
                    return controllers[key];
                }
                else
                {
                    return null;
                }
            }
    
            public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
            {
                Dictionary<string, HttpControllerDescriptor> dict
                = new Dictionary<string, HttpControllerDescriptor>();
                foreach (var asm in _config.Services.GetAssembliesResolver().GetAssemblies())
                {
                    //获取所有继承自ApiController的非抽象类
                    var controllerTypes = asm.GetTypes()
                    .Where(t => !t.IsAbstract && typeof(ApiController).IsAssignableFrom(t)).ToArray();
                    foreach (var ctrlType in controllerTypes)
                    {
                        //从namespace中提取出版本号
                        var match = Regex.Match(ctrlType.Namespace,
                        @"WebApi.Controllers.v(\d+)");
                        if (match.Success)
                        {
                            string verNum = match.Groups[1].Value;//获取版本号
                            string ctrlName = Regex.Match(ctrlType.Name, "(.+)Controller").Groups[1].Value;//从PersonController中拿到Person
                            string key = ctrlName + "v" + verNum;//Personv2为key
                            dict[key] = new HttpControllerDescriptor(_config, ctrlName, ctrlType);
                        }
                    }
                }
                controllers = dict;//因为项目启动的时候就会调用GetControllerMapping这个方法,这个方法主要是就获取所有的控制器,所以既然项目开始启动的时候就已经调用过这个方法了,已经获取到了所有的控制器了,为了避免我们在重新SelectController方法的时候二次调用,这里把已经取到的控制器字典缓存起来。
                return dict;
            }
        }
    }

    第三步:在WebApiConfig.cs中 将以下代码加入到Register方法最后面

    //将自定义的VersionControllerSelector注册到系统中
    config.Services.Replace(typeof(IHttpControllerSelector),new VersionControllerSelector(config));

    第四步: 在WebApi项目中的Controllers文件下分别创建v1和v2两个文件夹。 并在两个文件中分别创建一个PersonController.cs控制器
    例如:v1文件夹下的PersonController.cs控制器

    namespace WebApi.Controllers.v1
    {
        public class PersonController : ApiController
        {
            public string Get()
            {
                return "我是v1";
            }
        }
    }

    v2文件夹下的PersonController.cs控制器

    namespace WebApi.Controllers.v2
    {
        public class PersonController : ApiController
        {
            public string Get()
            {
                return "我是v2";
            }
        }
    }

    第五步:请求调用

    v1版本的App发起请求的URL是这样的:http://localhost:14483/api/v1/Person/Get
    v2版本的App发起请求的URL是这样的:http://localhost:14483/api/v2/Person/Get
    这样就达到了不同版本的APP在请求同名的控制器的时候,就会自动调用对应版本的名称空间下的同名控制器

    这里写图片描述

    展开全文
  • winForm如何调用WebApi接口

    万次阅读 2018-01-15 17:46:33
    因为本人接触的项目属于C/S结构的偏,一直没有机会接触webApi,所以一直觉得webApi很神秘。刚好最近有时间,所以我就在网上搜了一些webApi的资料,然后结合winform写了一Dome:  WebApi winform

    因为本人接触的项目属于C/S结构的偏多,一直没有机会接触webApi,所以一直觉得webApi很神秘。刚好最近有时间,所以我就在网上搜了一些webApi的资料,然后结合winform写了一个Dome:

        WebApi

    winform



    展开全文
  • 深入学习理解 RESTful Web 服务架构

    万次阅读 2018-02-08 00:25:56
    【简单由来】互联网以及科技发展,出现诸如Android,iOS ,网页等多个client来使用消费服务,所以出现了RESTful Web API架构 来统一接口,更好的服务于各个端,方便开发,部署,扩展,安全,缓存等等。【说明】...

    【简单由来】互联网以及科技发展,出现诸如Android,iOS ,网页等多个client来使用消费服务,所以出现了RESTful Web API架构 来统一接口,更好的服务于各个端,方便开发,部署,扩展,安全,缓存等等。

    【说明】RESTful Web API是 服务于多client与server的一种架构,不是具体的标准。只要符合RESTful 的约束要求,都是RESTful Web API。

    RESTful,Representational state transfer,或Resource Representational State Transfer

    【要点】
    1、简单理解就是,使用http的不同method(get, post, put, delete)请求url完成 访问
    2、区分stateless 与stateful (无状态与有状态),RESTful 需要无状态的api请求

    //错误实例
    GET http://MyService/NextPerson

    3、需要的状态stateful 可以用cookie或session或者token来完成,比如权限等等

    参考 The New RBAC: Resource-Based Access Control 使用shiro

    4、RESTful 需要定义好api的uri, 【不要包含动作】就是定义资源,和请求的方法,【规范化】,不然RESTful 会流于形式,【这是设计RESTful API的重点】

    //错误实例
    GET /deleteProduct/1

    其他帮助理解 RESTful 的文章:
    The Java EE 6 Tutorial—-What Are RESTful Web Services?
    百度百科–RESTful
    书—-REST实战
    RESTful Web Services: A Tutorial 【推荐阅读】
    wiki—-Representational state transfer 【RESTful 历史由来】
    知乎—REST 架构该怎么生动地理解?
    阮一峰—-RESTful API 设计指南
    segmentfault—RESTful 多参数定义资源问题

    展开全文
  • WebAPI 和 webservice的区别

    万次阅读 2016-05-17 10:13:25
    webapi无状态,相对webservice更轻量级。webapi支持如get,post等http操作http soap关系http:是一客户端和服务器端请求和应答的标准(TCP)。http协议其目的是为了提供一种发布和接收htttp页面的方法一http协议的...

    WebAPI 和 WebService的区别

    webapi用的是http协议,webservice用的是soap协议
    webapi无状态,相对webservice更轻量级。webapi支持如get,post等http操作

    http soap关系

    http:是一个客户端和服务器端请求和应答的标准(TCP)。http协议其目的是为了提供一种发布和接收htttp页面的方法

    一http协议的客户端与服务器的交互:由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,比如”HTTP/1.1 200 OK”,和(响应的)消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。

    soap 协议:它描述了一种在分散或分布式的环境中如何交换信息的轻量级协议。soap在http协议的基础上,一个基于XML的协议。

    不同:都是底层的通信协议,请求包的格式不同而已,soap包是XML格式,http纯文本格式。

    关系:SOAP是个通信协议, SOAP在HTTP协议的基础上,把编写成XML的REQUEST参数, 放在HTTP BODY上提交个WEB SERVICE服务器(SERVLET,ASP什么的) 处理完成后,结果也写成XML作为RESPONSE送回用户端, 为了使用户端和WEB SERVICE可以相互对应,可以使用WSDL作为这种通信方式的描述文件,利用WSDL工具可以自动生成WS和用户端的框架文件,SOAP具备把复杂对象序列化捆绑到XML里去的能力。
      

    WCF和WEB API我该选择哪个?
      1、当你想创建一个支持消息、消息队列、双工通信的服务时,你应该选择WCF
      2、当你想创建一个服务,可以用更快速的传输通道时,像TCP、Named Pipes或者甚至是UDP(在WCF4.5中),在其他传输通道不可用的时候也可以支持HTTP。
      3、当你想创建一个基于HTTP的面向资源的服务并且可以使用HTTP的全部特征时(比如URIs、request/response头,缓存,版本控制,多种内容格式),你应该选择Web API
      4、当你想让你的服务用于浏览器、手机、iPhone和平板电脑时,你应该选择Web API

    SOAP:Simple Object Access Protocol
    简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议( HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。

    HTTP协议: 应用层
    TCP协议 : 传输层

    HTTP协议详解之响应篇

    在接收和解释请求消息后,服务器返回一个HTTP响应消息。
    

    HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
    1、状态行格式如下:
    HTTP-Version Status-Code Reason-Phrase CRLF
    其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。
    状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
    1xx:指示信息–表示请求已接收,继续处理
    2xx:成功–表示请求已被成功接收、理解、接受
    3xx:重定向–要完成请求必须进行更进一步的操作
    4xx:客户端错误–请求有语法错误或请求无法实现
    5xx:服务器端错误–服务器未能实现合法的请求
    常见状态代码、状态描述、说明:
    200 OK //客户端请求成功
    400 Bad Request //客户端请求有语法错误,不能被服务器所理解
    401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
    403 Forbidden //服务器收到请求,但是拒绝提供服务
    404 Not Found //请求资源不存在,eg:输入了错误的URL
    500 Internal Server Error //服务器发生不可预期的错误
    503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
    eg:HTTP/1.1 200 OK (CRLF)

    2、响应报头后述

    3、响应正文就是服务器返回的资源的内容

    http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html

    展开全文
  • 《Asp.Net Web API》-----webApi的简单使用

    万次阅读 多人点赞 2016-09-29 16:16:08
    前言:在公司工作的时候,经理跟我说我们后台用的是WebApi技术,说它是一种轻量级的WCF,我以前用过WCF,但是对于WebApi有点不熟悉,但是经理说和WCF相似,我渐渐的对着门技术变得渐渐的好奇起来,下面由小编带领着...
  • 什么是接口测试

    万次阅读 2017-01-12 15:59:06
    什么是接口测试本来想写篇接口测试的基础文章,但看到这,就偷懒用Google翻译搬过来,想看原文的点这里http://www.softwaretestingmagazine.com/knowledge/api-testing-definition/,之后博主再整理更新更关于...
  • HTTP API 与Restful API 关系及区别

    千次阅读 2018-07-10 21:33:35
    https://blog.csdn.net/gyshun/article/details/80019741 在工作和面试中,...可以总结为一句话:REST是所有Web应用都应该遵守的架构设计指导原则。主要原则如下:1. C/S模型,通过统一接口通讯2. 层次化,可与多个服...
  • Restful api详解和rpc api 区别

    万次阅读 2014-08-18 15:39:19
    REST (REpresentation State Transfer) 描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。REST 指的是一组架构约束条件和原则...
  • 8种提升ASP.NET Web API性能的方法

    千次阅读 2016-04-09 15:26:36
    编写 Web API 十分容易,以致于很开发者没有在应用程序结构设计上花时间来获得很好的执行性能。  在本文中,我将介绍 8 项提高 ASP.NET Web API 性能的技术。  1、使用最快的 JSON 序列化工具
  • Java Web架构篇之API网关

    万次阅读 2019-06-17 10:46:26
    API网关封装了系统内部架构,为每客户端提供一定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。 API网关方式的核心要点是,所有的客户端和消费端都通过统一...
  • Web Api 创建及其使用

    千次阅读 2019-03-11 18:43:32
    由于创建博客,我需要尝试一些新的技术,新的思路,所以我没规规矩矩的写博客,用上了诸多以前没用的东西,比如现在这(我只是听过webapi我连webserver都只是用过两三次/手动滑稽) 昨天开始研究的,一直到现在,...
  • RESTful和SOAP比较

    万次阅读 2017-10-18 16:48:05
    1、RESTful 一种软件架构风格,设计风格而不是标准,只是提供了一组...REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fiel
  • API接口与webservice接口的区别

    万次阅读 2012-07-07 14:02:15
    其实现的原理并没有本质的区别,在应用开发层面上有以下区别: 1、Remoting可以灵活的定义其所基于的协议,如果定义为HTTP,则与Web Service就...3、Remoting一般需要通过一WinForm或是Windows服务进行启动,而Web
  • Web API 设计摘要

    千次阅读 2014-06-24 19:21:12
    最近读了一本微电子书 Brian Mulloy 所著《Web API Design》感觉颇收获,特对其内容做了整理摘要以便回顾其观点精华以指导日常工作中的设计思路。 本文主要讲述 Web API 设计,追求一种更务实的 REST ...
  • 针对ASP.NET Core Web API的先进架构

    千次阅读 2019-07-05 10:15:22
    .NET Core 最初是在2016年发布的,随着.NET Core 2.0的发布,微软拥有了下一通用、模块化、跨平台和开源的平台主版本。.NET Core已经创建了许...
  • Restful API 原理以及实现

    万次阅读 多人点赞 2015-11-18 16:25:49
    先说说API再说啥是RESRFUL API之前,咱先说说啥是API吧。API大家应该都知道吧,简称接口嘛。随着现在移动互联网的火爆,手机软件,也就是APP几乎快爆棚了。几乎任何一网站或者应用都会出一款iOS或者Android APP,...
  • WebApi 压力测试工具 ApaChe-Jmeter

    千次阅读 2018-09-21 00:29:38
    最近在做Asp.net Core Api,做微服务架构,后面会有相关文档介绍现用的架构,今天先记录一下压测工具。ApaChe-Jmeter! 架构大概是linux CentOS + Doker + Kong + Apollo .今天不细讲~~~ Jmeter是一接口压测工具...
  • OpenAPI和REST

    千次阅读 2011-08-02 10:38:55
    REST web服务 OpenAPI
  • 当然实际情况,肯定远比这复杂,数据库服务器和web 服务器可以部署台了. 数据库我们使用SQL server 即可(当然可以换成其他的,看自己了), Web服务器这边我们采用Web Api来实现接口,关于Web Api的知...
  • 从这一层开始我们开始不再创建.Framework类库项目,而是WebAPI项目。 右键解决方案名,添加WebAPI项目: 生成好后,将Model层中App.config的连接字符串加到Web.config中,将Model层中App.config的连接字符串加...
1 2 3 4 5 ... 20
收藏数 333,165
精华内容 133,266
关键字:

webapi 多个版本的架构设计