本文介紹C#事件請(qǐng)求處理程序的結(jié)構(gòu)和特點(diǎn)。

處理程序接口

當(dāng)您創(chuàng)建一個(gè)基于C#的函數(shù)時(shí),需要指定一個(gè)Handler方法,該方法在函數(shù)執(zhí)行時(shí)被執(zhí)行。這個(gè)Handler方法可以是Static方法或Instance方法。如果您想在Handler方法中訪問(wèn)IFcContext對(duì)象,則需要將該方法中的第二個(gè)參數(shù)指定為IFcContext對(duì)象。事件函數(shù)支持的Handler方法定義如下所示。

ReturnType HandlerName(InputType input, IFcContext context);  //包含IFcContext。
ReturnType HandlerName(InputType input); // 不包含IFcContext。
Async Task<ReturnType> HandlerName(InputType input, IFcContext context);
Async Task<ReturnType> HandlerName(InputType input);
函數(shù)計(jì)算支持在使用C#編寫的函數(shù)中應(yīng)用Async,此時(shí)函數(shù)的執(zhí)行會(huì)等待異步方法執(zhí)行結(jié)束。以下是對(duì)ReturnType、InputType和IFcContext的說(shuō)明。
  • ReturnType:返回對(duì)象可以是voidSystem.IO.Stream對(duì)象或者任何可以被JSON序列化和反序列化的對(duì)象。如果返回對(duì)象是Stream,該Stream內(nèi)容將直接在響應(yīng)體返回,否則返回對(duì)象被JSON序列化后,在響應(yīng)體返回。
  • InputType:輸入?yún)?shù)可以是System.IO.Stream或任何可以被JSON序列化和反序列化的對(duì)象。
  • IFcContext:函數(shù)的Context對(duì)象。更多信息,請(qǐng)參見(jiàn)上下文

事件請(qǐng)求處理程序類型

函數(shù)計(jì)算使用C#編寫函數(shù),需要引入Aliyun.Serverless.Core依賴包,可以通過(guò)以下方式在.csproj文件中引入該依賴包。

  <ItemGroup>
        <PackageReference Include="Aliyun.Serverless.Core" Version="1.0.1" />
  </ItemGroup>

Aliyun.Serverless.Core包為事件請(qǐng)求處理程序定義了兩個(gè)參數(shù)類型。

  • Stream Handler

    以流的方式接收輸入的event事件并返回執(zhí)行結(jié)果,您需要從輸入流中讀取調(diào)用函數(shù)時(shí)的輸入,處理完成后把函數(shù)執(zhí)行結(jié)果寫入到輸出流中來(lái)返回。

  • POCO Handler

    通過(guò)POCO(Plain old CLR objects)方式,您可以自定義輸入和輸出的類型,但是輸入和輸出的類型必須是POCO類型。

Stream Handler

一個(gè)最簡(jiǎn)單的Stream Handler示例如下所示。
using System.IO;
using System.Threading.Tasks;
using Aliyun.Serverless.Core;
using Microsoft.Extensions.Logging;

namespace Example
{
    public class Hello
    {
        public async Task<Stream> StreamHandler(Stream input, IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("Handle request: {0}", context.RequestId);
            MemoryStream copy = new MemoryStream();
            await input.CopyToAsync(copy);
            copy.Seek(0, SeekOrigin.Begin);
            return copy;
        }

        static void Main(string[] args){}
    }
}
示例解析如下。
  • 命名空間和類

    命名空間為Example,類名為Hello,方法名為StreamHandler,假設(shè)程序集名稱為HelloFcApp,則請(qǐng)求處理程序的配置為HelloFcApp::Example.Hello::StreamHandler

  • 參數(shù)Stream input

    處理程序的輸入,該示例的輸入類型為Stream。

  • 參數(shù)IFcContext context(可選)

    上下文對(duì)象,包含函數(shù)和請(qǐng)求的信息。

  • 返回值Task<Stream>

    返回值為Stream類型。

POCO Handler

一個(gè)最簡(jiǎn)單的POCO Handler示例如下所示。
using Aliyun.Serverless.Core;
using Microsoft.Extensions.Logging;

namespace Example
{
    public class Hello
    {
        public class Product
        {
            public string Id { get; set; }
            public string Description { get; set; }
        }

        // optional serializer class, if it’s not specified, the default serializer (based on JSON.Net) will be used.
        // [FcSerializer(typeof(MySerialization))]
        public Product PocoHandler(Product product, IFcContext context)
        {
            string Id = product.Id;
            string Description = product.Description;
            context.Logger.LogInformation("Id {0}, Description {1}", Id, Description);
            return product;
        }

        static void Main(string[] args){}
    }
}
除了Stream作為輸入輸出參數(shù),POCO(Plain old CLR objects)對(duì)象同樣也可以作為輸入和輸出。如果該P(yáng)OCO沒(méi)有指定特定的JSON序列化對(duì)象,則函數(shù)計(jì)算默認(rèn)使用JSON.Net進(jìn)行對(duì)象的JSON序列化和反序列化。具體解析如下。
  • 命名空間和類

    命名空間為Example,類名為Hello,方法名為PocoHandler,假設(shè)程序集名稱為 HelloFcApp, 則請(qǐng)求處理程序的配置為HelloFcApp::Example.Hello::PocoHandler

  • 參數(shù)Product product

    處理程序的輸入,該示例的輸入類型為Product Class。如果該P(yáng)OCO沒(méi)有指定特定的JSON序列化對(duì)象,則函數(shù)計(jì)算默認(rèn)使用JSON.Net進(jìn)行對(duì)象的JSON反序列化。

  • 參數(shù)IFcContext context(可選)

    上下文對(duì)象,包含函數(shù)和請(qǐng)求的信息。

  • 返回值Product

    返回值為POCO Product類型。如果該P(yáng)OCO沒(méi)有指定特定的JSON序列化對(duì)象,則函數(shù)計(jì)算默認(rèn)使用JSON.Net進(jìn)行對(duì)象的JSON序列化。

自定義序列化接口(Custom Serializer)

函數(shù)計(jì)算針對(duì)POCO Handler提供了默認(rèn)的基于JSON .NET的序列化接口。如果默認(rèn)的序列化接口不能滿足需求,您可以基于Aliyun.Serverless.Core中的接口IFcSerializer實(shí)現(xiàn)自定義序列化接口。

public interface IFcSerializer
{
    T Deserialize<T>(Stream requestStream);
    void Serialize<T>(T response, Stream responseStream);
}      

示例程序

函數(shù)計(jì)算官方庫(kù)包含使用各種處理程序類型和接口的示例應(yīng)用程序。每個(gè)示例應(yīng)用程序都包含用于輕松編譯部署的方法。