使用ASP.Net WebAPI构建REST服务

目录
  • 一、创建WebAPI应用程序
    • 1、Web API 1版本
    • 2、Web API 2版本
  • 二、路由
  • 三、返回值
    • 1、返回void
    • 2、返回普通对象
    • 3、返回HttpResponseMessage
    • 4、返回IHttpActionResult
  • 四、参数绑定
    • 1、默认绑定方式
    • 2、使用 [FromUri] 标记从URI中绑定参数
    • 3、使用 [FromBody] 标记从正文中绑定参数
    • 4、绑定多个参数
  • 五、客户端
    • 1、使用HttpClient库
    • 2、使用WebApi.Client库
  • 六、Self-Host
  • 七、调试工具
    • 1、帮助文档
    • 2、路由调试器
    • 3、执行过程跟踪

一、创建WebAPI应用程序

1、Web API 1版本

首先创建一个Asp.Net MVC 4 Web应用程序(我这里用的是Visual Studio 2012)。

在出来的模板中选择Web API。点击确定后,就创建了一个空的WebAPI服务。

2、Web API 2版本

点击确定后,就创建了一个空的WebAPI服务。此时只有一个空项目,还没有任何功能

在进行下一步之前,首先我们来看一下REST的基本操作模型,大致可以分为如下四种:

  • POST — 创建资源
  • GET — 检索资源
  • PUT — 更新资源
  • DELETE — 删除资源

非常经典的CRUD模型。

在Web API中实现这样一个的模型是非常简单的,直接使用向导建一个Controller即可

在Web API中生成默认的ValuesController

默认的模板内容如下:

public class ValuesController : ApiController
{
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
}

这其实已经帮我们实现了一个最基本的服务了,不过这个服务中只实现了Get,它支持如下两种中方式的URL访问(其它的方式也能访问,但没有具体的效果):

  • api/values 访问所有的Value列表
  • api/values/{id} 根据ID访问Value

按Ctrl + F5中执行,在浏览器中输入相应的地址即可看到结果

下面我们要做的就是完善它,实现一个简单的查询功能,这里我引用了微软官方的一个例子:

public class ProductsController : ApiController
{
        Product[] products = new Product[]
        {
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
        };

        public IEnumerable Get()
        {
            return products;
        }

        public IHttpActionResult Get(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }
}

public class Product
{
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
}

此时,我们就可以在浏览器中看到结果了(由于Controller改名字了,此时的地址就变成了api/products)

到此为止,一个基于Asp.net Web API的 简单的REST Web服务就构建完成了,由于篇幅所限,这里就不做更多的介绍了,跟多信息可以参看微软官方文档:Getting Started with ASP.NET Web API 2

备注:WebAPI升级到 WebAPI 2如下命令更新web Api:

Install-Package Microsoft.AspNet.WebApi

二、路由

REST并没有像传统的RPC服务那样显式指定了服务器函数的访问路径,而是将URL根据一定的规则映射为服务函数入口,这个规则就称之为路由。Asp.Net WebAPI的路由方式和Asp.Net MVC是相同的,它支持两种路由方式,传统的路由映射和特性路由。 路由规则WebApiConfig.cs中定义。

它的默认内容如下:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

它默认注册了两种路由规则,第一行注册的是特性路由,第二行注册的则是传统的映射路由。默认情况下,由于我们没有编写特性路由规则,则是按照传统的Controller方式映射路由。

关于路由规则,MSDN文档ASP.NET 路由介绍得非常详细,但由于其介绍得太详细了,反而不容易得其门而入,这里我只拿默认的路由规则来简单但的介绍一下我的理解,它的uri格式是这样的"api/{controller}/{id}",其中id是可选的。拿前文的例子来说吧,

  • 当我们对api/products地址进行访问的时候,系统则会首先找到名为ProductsController的控制器。
  • 然后,根据访问方式查找函数,由于这里是Get操作,则查找Get开头的函数, 这里会找到Get()和Get(int id)两个重载版本。
  • 最后,根据参数来匹配具体的函数,因为这里没有带参数id。因此匹配到了Get()函数,返回了所有的集合。

另外,这里也有几个常用的衍生规则:

  • 根据操作方式找函数的时候,只需要匹配首部即可,因此我们编写函数的时候写成Get()和GetProduct()都是可以的。,
  • 根据操作方式找函数的时候查找的时候不分大小写,因此写成Get()或get()都是可以的

当我们使用带参数的版本时候,也有几个需要注意的地方:

  • 参数名不分大小写,我们写成id或ID都是可以的
  • 参数名要求严格匹配的,我们写成ID2是不行的,此时则会匹配到错误的结果Get()

默认的规则虽然大多数的时候还是比较方便的,但是很多时候我们需要手动指定个性化的路由规则。例如,我们可以自定义一个按名称来查询的url:api/products/name=xxx。这个时候则可以用特性路由快速的实现了:

[Route("api/{controller}/name={name}")]
public IHttpActionResult GetByName(string name)

关于特性路由,MSDN原文Attribute Routing in ASP.NET MVC 5介绍得非常详细。

三、返回值

Asp.Net WebAPI服务函数的返回值主要可以分为void、普通对象、HttpResponseMessag、IHttpActionResult e四种,本文这里简单的介绍一下它们的区别。

1、返回void

返回void一般常用于Put和Delete函数。

public void Delete(int id)
{
}

当服务函数执行完成后,服务器端并不是啥都不干直接把客户端给断掉,而是发送一个标准的204 (No Content)的Http应答给客户端。

HTTP/1.1 204 No Content
    Cache-Control: no-cache
    Pragma: no-cache
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXNcMQ==?=
    X-Powered-By: ASP.NET
    Date: Fri, 02 May 2014 13:32:07 GMT

2、返回普通对象

返回普通对象时,服务器将返回的对象序列化后(默认是json),通过Http应答返回给客户端。例如,

public class ValuesController : ApiController
{
        public string Get()
        {
            return "hello";
        }
}

此时的返回结果是:

HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?=
    X-Powered-By: ASP.NET
    Date: Fri, 02 May 2014 12:54:18 GMT
    Content-Length: 7
"hello"

异步返回普通对象:

WebAPI也是支持异步返回对象的:

    public async Task<string> Get()
    {
        await Task.Delay(100);
        return "hello";
    }

异步返回的时候,服务器异步等待函数执行完成后再将返回值返回给对象。由于这个过程对于客户端来说是透明的,这里就不列举报文了。

3、返回HttpResponseMessage

HttpResponseMessage是标准Http应答了,此时服务器并不做任何处理,直接将HttpResponseMessage发送给客户端。

public HttpResponseMessage Get()
{
        var response = Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StringContent("hello", Encoding.UTF8);

        return response;
}

此时的返回结果如下:

HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Length: 5
    Content-Type: text/plain; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?=
    X-Powered-By: ASP.NET
    Date: Fri, 02 May 2014 13:09:57 GMT
hello

可以看到,这里返回的content-type仍然是原始定义的text类型,而不是json。要实现想上面的例子所示的结果,则需要将Get函数改写为如下形式

public HttpResponseMessage Get()
{
        return Request.CreateResponse(HttpStatusCode.OK, "hello");
}

4、返回IHttpActionResult

IHttpActionResult是Web API 2 中引入的一个接口,它的定义如下:

public interface IHttpActionResult
{
        Task ExecuteAsync(CancellationToken cancellationToken);
}

从它的定义可以看出,IHttpActionResult是HttpResponseMessage的一个工厂类,最终还是用于构建HttpResponseMessage返回,由于它可以取消,因而可以实现更为强大的返回功能(如流传输)。当服务函数返回IHttpActionResult对象时,服务器执行该对象的ExecuteAsync函数,并异步等待至函数完成后,获取其返回值HttpResponseMessage输出给客户端。

IHttpActionResult是WebAPI中推荐的标准返回值,ApiController类中也提供了不少标准的工厂函数方便我们快速构建它们,如BadRequest,Conflict,Ok,NotFound等,一个简单的示例如下:

public IHttpActionResult Get(int id)
{
        var product = products.FirstOrDefault((p) => p.Id == id);
        if (product == null)
        {
            return NotFound();
        }
        return Ok(product);
}

四、参数绑定

1、默认绑定方式

WebAPI把参数分成了简单类型和复杂类型:

  • 简单类型主要包括CLR的primitive types,(int、double、bool等),系统内置的几个struct类型(TimeSpan、Guid等)以及string。对于简单类型的参数,默认从URI中获取。
  • 复杂类型的数据也可以直接作为参数传入进来,系统使用media-type formatter进行解析后传给服务函数。对于复杂类型,默认从正文中获取。

例如,对于如下函数

HttpResponseMessage Put(int id, Product item)

其id默认从url中获取,其item默认从正文中获取。

2、使用 [FromUri] 标记从URI中绑定参数

我们可以使用 [FromUri] 标记强制从URI中绑定参数,例如

public class GeoPoint
{
        public double Latitude { get; set; }
        public double Longitude { get; set; }
}

public ValuesController : ApiController
{
        public HttpResponseMessage Get( [FromUri]  GeoPoint location) { ... }
}

这样,Get参数就是从URI中获取了读取GeoPoint对象。需要注意的是,此时我们必须将GeoPoint对象的属性在URI中传入: http://localhost/api/values/?Latitude=47.678558&Longitude=-122.130989 。

这种默认的序列化方式比较冗长,我们也可以自定义反序列化格式为类似这样的形式:http://localhost/api/values/?location=47.678558,-122.130989,具体方法请参看参考文档 Type Converters 的一节。

3、使用 [FromBody] 标记从正文中绑定参数

同样,我们可以使用 [FromBody] 标记强制从正文中绑定参数,例如

public HttpResponseMessage Post( [FromBody] string name)

将强制从FormData等非URL参数中读取数据

4、绑定多个参数

前面介绍的方式中,只能从URI中绑定一个参数,虽然可以通过传入复杂类型解决多参数的问题,但很多时候不如在URI中来得直接。此时,我们则可以使用前面介绍的特性路由来实现多参的绑定,例如:

[Route("api/{controller}/{year}/{month}/{day}")]
public string Get(int year, int month, int day)
{
        return string.Join(",", year, month, day);
}

参考文档: http://www.asp.net/web-api/overview/formats-and-model-binding

五、客户端

WebAPI是标准的Http协议,支持Http协议的客户端(如浏览器)都可以访问。但是,有的时候我们如果想在自己的程序中使用WebAPI时,此时就要实现自己的客户端了。

1、使用HttpClient库

我之前介绍过在.Net 4.5中新增的HttpClient库,它对Http操作实现了非常好的封装。我们可以通过它实现Http访问,例如,我们对前文所示的API进行一次Post操作:

// POST: api/Values
public void Post(Product value)
{
}

首先对HttpClient进行一些初始化操作:

var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:1282/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

这里主要进行了两部操作:1. 定义了默认的基地址,减少后续的URL长度,2. 定义了默认的接受的数据类型为Json。

下一步就要开始对Product对象的内容编码,默认是xml或json,这里我选择相对简单的json:

var product = new Product() { Id = 1, Name = "food" };
var content = Newtonsoft.Json.JsonConvert.SerializeObject(product);
var httpContent = new StringContent(content, Encoding.UTF8);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };
await httpContent.LoadIntoBufferAsync();
var rsp = await client.PostAsync("api/values", httpContent);

从上面的代码可以看出,由于WebAPI不像WCF那样能自动生成客户端代码,需要我们自己封装对象,上面光封装对象就用了四行代码,对于不熟悉HttpClient朋友来说还是比较容易出错的。因此微软提供了一系列扩展函数方便我们简化这一过程。

2、使用WebApi.Client库

在Nuget中安装WebApi.Client库

这个库安装后会在引用中增加一个System.Net.Http.Formatting的程序集,它主要提供了一系列扩展函数(其实装这个库顺带也会把HttpClient和Json.Net一并安上),现在上面的代码就可以简化如下了:

var product = new Product() { Id = 1, Name = "food" };
var rsp = await client.PostAsJsonAsync("api/values", product);

除了PostAsJsonAsync这个扩展函数外,还提供了PostAsXmlAsync这种以XML传输的方式。同样,Put也有PutAsJsonAsync和PutAsXmlAsync的扩展版本。对于Get,虽然也提供了扩展函数,但是使用的方式稍有不同:

var rsp = await client.GetAsync("api/values/1");
rsp.EnsureSuccessStatusCode();
var product = await rsp.Content.ReadAsAsync();

对于Delete,却没有提供扩展函数,可能是官方认为Delete直接在URL中就传ID就够用了,没必要在Request中封装消息了吧。

限于篇幅,今天就介绍到这里了,更多内容的可以参看官方文档:http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client

六、Self-Host

Asp.Net WebAPI生成的是一个程序集,并不是独立的进程,因此,要运行的时候必须将其承载在相应的宿主上,一般比较常见的是IIS承载。

很多时候,我们为了简化部署或者功能集成,需要将其承载到独立的进程上,这种方式一般称之为Self-Host,本文就简单的介绍一下WebAPI的SefHost方法。

首先在Nuget上安装Microsoft.AspNet.WebApi.SelfHost库。

附上我们的WebAPI控制器

public class ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        return new string[] { "111", "222" };
    }
}

接下来的工作就是启动我们的服务器了。

    class Program
    {
        static void Main(string[] args)
        {
            //Assembly.Load("WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");    //加载外部程序集
            var config = new HttpSelfHostConfiguration("http://localhost:8080");

            config.Routes.MapHttpRoute(
                "API Default", "api/{controller}/{id}",
                new { id = RouteParameter.Optional });

            using (var server = new HttpSelfHostServer(config))
            {
                server.OpenAsync().Wait();
                Console.WriteLine("Press Enter to quit.");
                Console.ReadLine();
            }
        }
    }

从上面的代码可以看出,配置文件和Asp.Net程序中基本上是一样的,如果是直接用Asp.Net项目中生成的DLL的话,我们也可以直接用其WebApiConfig.Register的方法来进行配置的(需要像第一行注掉的那样使用Assembly.Load加载程序集)。下面一段就是启动服务器了,更多内容可以参看MSDN文档:http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api

值得一提的是,SelfHost是在一个独立进程中启动了Http服务,也可以是说,它是一个mini版的Http服务器,我之前介绍过通过HttpListener实现简单的Http服务,到了现在,用WebAPI的SelfHost方式是可以更加快捷的实现扩展性更好的Mini Http服务器的,当我们需要一个简单的Http服务的时候,可以使用这种方式。

除了这种方式外,微软更加推荐用功能更加强大的OWIN来承载WebAPI服务。

另外,除了IIS、SelfHost等方式外,云时代发布到Windows Azure也是非常便捷的,这里就不做多少介绍了,详细内容请参看MSDN文档:http://www.asp.net/web-api/overview/hosting-aspnet-web-api 。

七、调试工具

由于WebAPI本身是基于HTTP协议的,在开发过程中,我们可以使用浏览器或Fiddler等HTTP工具辅助开发。与此同时,微软也提供了一些工具方便我们调试,使得开发更加简单快捷,本文就简单的介绍一下这几个工具。

1、帮助文档

通过帮助文档,我们可以非常直观的看到控制器生成了那些路由,通过这些接口文档可以非常方便的指导客户端开发。

要开启帮助文档,可以参看这篇文章: http://www.asp.net/web-api/overview/creating-web-apis/creating-api-help-pages

2、路由调试器

当我们应用了大量的路由规则和自定义路由的时候,有的时候,就会出现一条路由具体走的那条规则的情况,这个时候,则可以通过路由调试器来帮助我们进行分析和定位:

要启用路由调试器,可以参看如下地址:http://blogs.msdn.com/b/webdev/archive/2013/04/04/debugging-asp-net-web-api-with-route-debugger.aspx

3、执行过程跟踪

执行过程跟踪工具则可以非常直观的打印出其交互过程,可以非常方便的查看我们是否进行了正确的输入和获得了相应的输出。

要启用执行过程跟踪,可以参考这个地址:http://www.asp.net/web-api/overview/testing-and-debugging/tracing-in-aspnet-web-api

不过它将执行过程打印在OutPut窗口中了,有的时候不是很方便,可以将其修改一下,用SignalR打印在网页或第三方客户端上,加一些输出信息高亮的话,则更加方便一些。

到此这篇关于使用ASP.Net WebAPI构建REST服务的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用ASP.NET Web API构建Restful API

    目录 一.前言 二.获取所有数据 三.获取详情 四.新增数据 五.修改数据 六.删除数据 七.特性路由 (1) 基本路由映射 (2) 路由映射参数 (3) 多重特性路由 (4) 缺省参数路由 (5) 参数约束路由 (6) 通配符(*)路由变量 (7) 路由映射复杂参数 (8) 路由前缀 一.前言 RESTful API 是基于HTTP协议产生的一种相对简单的API设计方案: RESTful 的核心是 everything is a “resource”,所有的HTTP action,都应该是相应

  • ASP.NET Core构建OData查询Restful API

    目录 前言: 一.建构 OData 实体模型 二.配置 OData 中间件 三.OData 实现 Restful API 查询 参考文档 前言: 本文使用 .NET Core SDK 3.1 的版本. OData 是 Open Data Protocol 的简写, OData 允许以简单和标准的方式创建和使用可查询和互操作的 Restful API. 官方文档访问 OData - Basic Tutorial 创建 Web API 项目,并引入 OData 相关的 NuGet 包: dotnet

  • asp.net MVC下使用rest的方法

    前言 最近做了下个MVC的项目,需要用到rest接口,与java写的应用程序通信,包括数据的接收和发送,那么我将用实用的角度来全面的讲解一下它的使用方法 一.创建rest服务 首先创建一个Asp.Net Web应用程序(我这里用的是Visual Studio 2013,它已经内置了Web API2). 在出来的模板中选择Empty(空项目),并勾选WebAPI.点击确定后,就创建了一个空的WebAPI服务. 此时只有一个空项目,还没有任何功能,在进行下一步之前,首先我们来看一下REST的基本操作

  • 使用ASP.Net WebAPI构建REST服务

    目录 一.创建WebAPI应用程序 1.Web API 1版本 2.Web API 2版本 二.路由 三.返回值 1.返回void 2.返回普通对象 3.返回HttpResponseMessage 4.返回IHttpActionResult 四.参数绑定 1.默认绑定方式 2.使用 [FromUri] 标记从URI中绑定参数 3.使用 [FromBody] 标记从正文中绑定参数 4.绑定多个参数 五.客户端 1.使用HttpClient库 2.使用WebApi.Client库 六.Self-Ho

  • 使用VS2022在ASP.NET Core中构建轻量级服务

    目录 1. 使用 VS2022 创建 ASP.NET Core 项目 2. 在 ASP.NET Core 中启用一个轻量级的服务 3. 在 ASP.NET Core 中使用 IEndpointConventionBuilder 扩展方法 4. 在 ASP.NET Core 中使用轻量级服务检索记录 5. 在 ASP.NET Core 中使用轻量级服务创建记录 6. 在 ASP.NET Core 中使用轻量级服务删除记录 7. ASP.NET Core 中轻量级服务的配置方法 8. 在 ASP.N

  • ASP.NET WebAPI连接数据库的方法

    ASP.NET Web API 是一种框架,用于轻松构建可以访问多种客户端(包括浏览器和移动设备)的 HTTP 服务. ASP.NET Web API 是一种用于在 .NET Framework 上构建 RESTful 应用程序的理想平台. 本文主要实现ASP.NET WebAPI 连接数据库获取数据,并以Json字符串格式返回. 1.创建ASP.NET Web Application(.NET Framework)项目: 2.选择Web API: 3.创建新项目完成: 在ValuesContr

  • ASP.net WebAPI跨域调用问题的解决方法

    发现问题 最近在做一个项目,前端是VUE,后端是WebAPI,业务也就是一些实体的增删改查.在项目开始的时候我就预计到有跨域的问题,所以也找了一下资料,在Web.Config里面加上了配置信息: <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-A

  • ASP.NET State service状态服务的问题解决方法

    异常详细信息: System.Web.HttpException: 无法向会话状态服务器发出会话状态请求.请确保已启动 ASP.NET State service,并且客户端和服务器端口是相同的.如果服务器位于远程计算机上,请检查 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection 的值,确保服务器接受远程请求. 这是因为ASP.NET State s

  • Spring Security 构建rest服务实现rememberme 记住我功能

    Spring security记住我基本原理: 登录的时候,请求发送给过滤器UsernamePasswordAuthenticationFilter,当该过滤器认证成功后,会调用RememberMeService,会生成一个token,将token写入到浏览器cookie,同时RememberMeService里边还有个TokenRepository,将token和用户信息写入到数据库中.这样当用户再次访问系统,访问某一个接口时,会经过一个RememberMeAuthenticationFilt

  • 使用Python FastAPI构建Web服务的实现

    FastAPI是一个使用 Python 编写的 Web 框架,还应用了 Python asyncio 库中最新的优化.本文将会介绍如何搭建基于容器的开发环境,还会展示如何使用 FastAPI 实现一个小型 Web 服务. 起步 我们将使用 Fedora 作为基础镜像来搭建开发环境,并使用 Dockerfile 为镜像注入 FastAPI.Uvicorn和 aiofiles这几个包. FROM fedora:32 RUN dnf install -y python-pip \ && dnf

  • vuecli项目构建SSR服务端渲染的实现

    服务端渲染(SSR) 将一个 Vue 组件在服务端渲染成 HTML 字符串并发送到浏览器,最后将这些静态标记"激活"为可交互应用程序的过程就叫服务端渲染(SSR) 服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器和客户端上运行 为什么使用 服务端渲染(SSR) 更好的 SEO:传统的 spa 页面数据都是异步加载,搜索引擎爬虫无法抓取,服务端渲染(SSR)使搜索引擎爬虫抓取工具可以直接查

  • golang构建HTTP服务的实现步骤

    目录 HTTP Handler ServeMux Server 创建HTTP服务 http注册路由 开启监听 处理请求 参考:    一个go最简单的Http服务器程序 package main import ( "fmt" "net/http" ) func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "hello world") } func m

  • docker 基于golang镜像构建 ssh服务的方法

    下面给大家介绍下docker 基于golang镜像构建 ssh服务的代码,具体内容如下所示: # golang:latest镜像 FROM ee23292e2826 # 作者 MAINTAINER dechao@qq.com # 添加Golang环境变量 ENV GOPROXY https://goproxy.cn,direct ENV GO111MODULE on # 配置apt-get源 ADD sources.list /etc/apt/ # 更新apt-get源 安装ssh服务 修改ro

随机推荐