Web服务器Raspkate的RESTful API
基于轻量型Web服务器Raspkate的RESTful API的实现
在上一篇文章中,我们已经了解了Raspkate这一轻量型Web服务器,今天,我们再一起了解下如何基于Raspkate实现简单的RESTful API。
模块
首先让我们了解一下“模块”的概念。Raspkate的模块包含了一组能够提供完整业务功能的HTTP处理器(Handler),例如,在Raspkate的源代码库中,默认提供了两个模块:Default和RaspberryPi,它们分别位于两个不同的C#项目中:
- Raspkate.Modules.Default
 - Raspkate.Modules.RaspberryPi
 
Default模块包含了一个标准的静态文件访问服务/处理器,以及一个能够读取并返回服务器信息的RESTful API控制器;而RaspberryPi模块则提供了一个访问树莓派信息页静态文件的处理器,以及一个读取树莓派信息的RESTful API控制器。当然,在这里静态文件访问处理都是由FileHandler负责,而RESTful API的处理则由ControllerHandler完成。虽然这两个模块使用了相同类型的Handler,但它们所专注的业务功能完全不同,而且它们是相互隔离,独立执行的。
Raspkate中每个模块都被存放于modules目录下的某个子目录中,在Raspkate服务启动时,会扫描modules目录下的所有程序集,定位所有继承于RaspkateModule类的子类,并根据类型定义对Handler进行初始化然后注册到Raspkate服务中,以便这些Handler能够为HTTP请求提供服务。当然,这些模块也可以放在其它目录下,但这就需要修改Raspkate服务的配置文件RaspkateService.exe.config,把模块所在的目录添加到modules节点下,例如:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
 | 
<?xml version="1.0" encoding="utf-8" ?><configuration>  <configSections>    <section name="raspkateConfiguration" type="Raspkate.Config.RaspkateConfiguration, Raspkate"/>  </configSections>    <modules>      <add path="modules"/>      <add path="d:\\test" relative="false" />    </modules>  </raspkateConfiguration></configuration> | 
在模块的注册类型中(也就是继承于RaspkateModule类的子类中),只需要返回该模块能够提供的Handler实例即可。接下来,让我们一起看看,如何开发一个自己的模块,并通过注册ControllerHandler,向调用者提供RESTful API服务。
案例:计算器
最简单的不过就是计算器运算:加、减、乘、除。那么最最简单的就是计算两个整数的和,好吧,就以这个为例,开始我们的RESTful API开发之旅。
首先,打开Visual Studio 2013,新建一个C#类库(Class Library)项目,项目命名为RaspkateCalculatorModule,注意.NET Framework至少选择4.5.2以上(老版本的Framework除了2.0以外,Microsoft都不再官方支持了)。成功创建项目后,添加对Raspkate.dll的引用。
然后,在这个项目中新建一个名为CalculatorController的类,代码如下:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
 | 
[RoutePrefix("calc")]public class CalculatorController : RaspkateController{    [HttpGet]    [Route("add/{a}/{b}")]    public int Add(int a, int b)    {        return a + b;    }} | 
接着,在这个项目中新建一个名为Module的类,代码如下:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
 | 
internal sealed class Module : RaspkateModule{    public Module(ModuleContext context)        : base(context)    { }    protected override IEnumerable<IRaspkateHandler> CreateHandlers()    {        yield return new ControllerHandler("CalculatorController",             new [] { typeof(CalculatorController) });    }} | 
OK,万事俱备,只欠东风啦!回到Raspkate中,将RaspkateService.exe.config稍微改动一下,将该模块的输出目录添加到modules节点中,即可直接启动RaspkateService.exe程序了:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
 | 
<?xml version="1.0" encoding="utf-8" ?><configuration>  <configSections>    <section name="raspkateConfiguration" type="Raspkate.Config.RaspkateConfiguration, Raspkate"/>    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>  </configSections>    <modules>      <add path="modules"/>      <add path="C:\Users\chenqn\Documents\visual studio 2013\Projects\RaspkateCalculatorModule\RaspkateCalculatorModule\bin\Debug" relative="false"/>    </modules>  </raspkateConfiguration>  <log4net>    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">      <layout type="log4net.Layout.PatternLayout">        <conversionPattern value="%utcdate{DATE} [%thread] %level %logger - %message%newline"/>      </layout>    </appender>    <appender name="FileAppender" type="log4net.Appender.FileAppender">      <file value="logs/raspkate.log" />      <appendToFile value="true" />      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />      <layout type="log4net.Layout.PatternLayout">        <conversionPattern value="%date [%thread] %level %logger - %message%newline" />      </layout>    </appender>    <root>      <level value="INFO"/>      <appender-ref ref="ConsoleAppender"/>      <appender-ref ref="FileAppender" />    </root>  </log4net>  <startup>    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />  </startup></configuration> | 
启动程序后,你可以在输出的日志中注意到,CalculatorController已经被注册到ControllerHandler当中,进而可以开始提供HTTP请求的服务了:

请打开你的浏览器,在地址栏中输入:
那么,你应该看到的是:

看来Raspkate服务已经将计算结果返回给你了。怎么样?使用Raspkate开发RESTful API是不是非常快捷?接下来让我们看看更加有意思的特性。
案例:计算器(进阶)
刚才我们的计算器还是太简单,接下来我打算让这个计算器能够计算复数(包括虚数部分)的乘法。同学们是否还记得复数相乘的计算公式?

OK,也就是我们的RESTful API需要接收两个复数,每个复数都要包含实数 r 和虚数 i 两个部分,返回值也应该包含实数和虚数两个部分。那么,我们的CalculatorController就可以写成这样:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
 | 
[RoutePrefix("calc")]public class CalculatorController : RaspkateController{    [HttpGet]    [Route("add/{a}/{b}")]    public int Add(int a, int b)    {        return a + b;    }    [HttpPost]    [Route("mul")]    public dynamic Multiplicity([FromBody] dynamic input)    {        var a = input.x.r; // 第一个数的实数部分        var b = input.x.i; // 第一个数的虚数部分        var c = input.y.r; // 第二个数的实数部分        var d = input.y.i; // 第二个数的虚数部分        return new { z = new { r = a * c - b * d, i = b * c + a * d } };    }} | 
重新运行Raspkate服务,打开能够发出HttpPost请求的测试客户端(我用的是Fiddler),看看我们的程序是否可以正确执行:

测试成功,RESTful API已经以JSON格式返回了我们需要的计算结果。
总结
从上面的演示可以看到,Raspkate服务中RESTful API的实现,沿用了类似微软ASP.NET Web API的编程习惯,包括:
- Controller的编程模型(ASP.NET Web API中使用ApiController作为基类,此处使用RaspkateController作为基类)
 - Attribute Routing
 - HttpGet和HttpPost两种HTTP方法(其它的暂未实现)
 - FromBody特性修饰符,使得方法的某些参数可以直接从HTTP Post Body中取值
 - 对dynamic类型、匿名类型的支持
 
相比之下,Raspkate服务所提供的RESTful API编程更为简单快捷。今后如果这部分的确有应用的话,可以对整个结构作进一步完善。
Web服务器Raspkate的RESTful API的更多相关文章
- 基于轻量型Web服务器Raspkate的RESTful API的实现
		
在上一篇文章中,我们已经了解了Raspkate这一轻量型Web服务器,今天,我们再一起了解下如何基于Raspkate实现简单的RESTful API. 模块 首先让我们了解一下"模块&quo ...
 - 软件架构,WEB - REST架构,RESTful API
		
参考 https://www.zhihu.com/question/27785028/answer/48096396 wiki太学术化了 http://www.ruanyifeng.com/blog/ ...
 - restful api 错误
		
简介 随着移动开发和前端开发的崛起,越来越多的 Web 后端应用都倾向于实现 Restful API.Restful API 是一个简单易用的前后端分离方案,它只需要对客户端请求进行处理,然后返回结果 ...
 - Restful API 中的错误处理
		
简介 随着移动开发和前端开发的崛起,越来越多的 Web 后端应用都倾向于实现 Restful API. Restful API 是一个简单易用的前后端分离方案,它只需要对客户端请求进行处理,然后返回结 ...
 - WildFly8(JBoss)默认web服务器-------Undertow
		
Java微服务框架之Undertow 一.Undertow简介: Undertow 是红帽公司(RedHat)的开源产品,是 WildFly8(JBoos) 默认的 Web 服务器. 官网API给出一 ...
 - Yii2 Restful API 原理分析
		
Yii2 有个很重要的特性是对 Restful API的默认支持, 通过短短的几个配置就可以实现简单的对现有Model的RESTful API 参考另一篇文章: http://www.cnblogs. ...
 - Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器
		
最近在业余时间玩玩树莓派,刚开始的时候在树莓派里写一些基于wiringPi库的C语言程序来控制树莓派的GPIO引脚,从而控制LED发光二极管的闪烁,后来觉得,是不是可以使用HTML5+jQuery等流 ...
 - ASP.NET Core Web API 开发-RESTful API实现
		
ASP.NET Core Web API 开发-RESTful API实现 REST 介绍: 符合REST设计风格的Web API称为RESTful API. 具象状态传输(英文:Representa ...
 - 移动互联网实战--Web Restful API设计和基础架构
		
前言: 在移动互联网的大潮中, Web Restful API逐渐成为Web Server重要的一个分支. 移动端和服务端的交互, 主流的方式还是通过Http协议的形式来进行. 请求以Get/Post ...
 
随机推荐
- Android菜鸟的成长笔记(6)——剖析源码学自定义主题Theme
			
原文:Android菜鸟的成长笔记(6)--剖析源码学自定义主题Theme 还记得在Android菜鸟的成长笔记(3)中我们曾经遇到了一个问题吗?"这个界面和真真的QQ界面还有点不同的就是上 ...
 - SDL 简介
			
SDL 简介 什么是SDL? 即 Simple DirectMedia Layer,使用 LGPL 许可证. 免费的跨平台多媒体应用编程接口 用于游戏.游戏开发工具.模拟器.样本演示.多媒体应用等 它 ...
 - mysql 主从同步出问题,重新修复从库 - web架构研究
			
mysql 主从同步出问题,重新修复从库 - web架构研究 mysql 主从同步出问题,重新修复从库 0 昨天由于操作失误,在从库上执行一堆sql之后,导致主从同步错误,并且已 ...
 - myBatis 基础测试 表关联关系配置 集合 测试
			
myBatis 基础测试 表关联关系配置 集合 测试 测试myelipse项目源码 sql 下载 http://download.csdn.net/detail/liangrui1988/599388 ...
 - 原型链(__proto__)
			
前面详细的解释了new的几个步骤,其中随意带过了一下原型链的概念,如果细读那篇文章,基本对原型也能有所理解. 原型有两个关键属性,一个是 __proto__ 一个是 prototype ,了解了这两个 ...
 - SilkTest Q&A 4
			
Q31.如何在inc文件里面写函数? A31.在你在inc文件(例如demo.inc)里写好函数以后,你需要使用Use path/Use file来指定指定它们. 在SilkTest中->Opt ...
 - information_schema模式表介绍 processlist
			
在mysql里,我们一般通过show (full)processlist查看当前连接情况,处理各种数据库问题.现在在information_schema模式下,5.5以后增加了processlist表 ...
 - JavaScript学习总结1
			
/***我是切割线 的開始***/ //利用prototype属性能够加入公有属性和方法 function myConstructor2(){ this.a='大灰狼'; }; //声明构造函数,能够 ...
 - 图像编程学习笔记2——bmp位图平移
			
以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序. 2.1 平移 平移(translation)变换大概是几何变换中最简单的一种了 ...
 - JAVA WEB开发环境搭建教程
			
一.下载安装JDK,配置好环境变量.(例如我JDK安装的目录为:C:\Program Files (x86)\Java\jdk1.6.0_10 ) 点击我的电脑-属性-系统设置(高级系统设置) ...