透过1组RESTful API揭破CQCR-VS系统效用语言

命令

询问普通会映射到GET方法,而下令则要求映射到POST、PUT、DELETE和PATCH方法。将HTTP谓词映射到CRUD操作是壹种流行的历史观,但在实际世界中很少能够将谓词和数据库操作壹1对应。实际上,REST
API并不在对持久化存款和储蓄之上的二个简练包装,相反,它是指点用户去探听事情领域、操作与工作流的一扇门。由此它必须能够不借助于于特定的谓词去表述有些维度的来意。

1种常见的不二等秘书技是选择远程进度调用(RPC)风格的能源,比如/api/InventoryItem/{id}/rename。纵然它看起来确实去除了对某种谓词的借助,但它违反了REST面向能源的变现本事。我们须要记住,财富是三个名词,HTTP谓词则意味动词和动作,而自描述的新闻(REST的核心之一)则是公布此外维度音信和意向的一手。实际上,在HTTP新闻中所蕴涵的通令就应该能够描述任何人为的操作了。可是,完全依赖于请求体中的新闻也有它自个儿的标题,因为请求体平常是作为流传递的,要在辩认出它的具体操作在此以前得到整个请求体有时是不容许成功的,而且那也不是1种明智的做法。这里,大家将显示1种基于伍LMT中的第四等级(即世界模型)管理请求的点子,命令的体系将富含在Content-Type头中的有个别参数内。

PUT /api/InventoryItem/4454c398-2fbb-4215-b986-fb7b54b62ac5 HTTP/1.1  
Accept:application/json, text/plain, */* 
Accept-Encoding:gzip,deflate,sdch 
Content-Type:application/json;domain-model=RenameInventoryItemCommand

这么就能够将请求正确地输送给服务端相应的管理办法了。那那种办法是不是将过多的消息败露给客户端了啊?并非如此。输入输出新闻的schema(以及名称)是公然领域的一片段,客户端必须能够全部地访问到它,因而它们依据于schema也是在我们所预期的。

有关客户端的贯彻只用了最一些些的代码,那里运用了三个AngularJS*的装饰(decorator)封装了$http劳务,它能够读取这么些原型的回到内容,并且能够在Content-Type头中加入额外的参数音信。只要保持JavaScript构造函数*的称号不改变就从未有过难题。

作者们早已消除了辨认当前正被调用的法子的主题材料,接下去须求将下令依照语义映射到相应的HTTP谓词。在将指令映射到谓词时,采纳准确谓词的要紧不仅仅在于语义,同样要思索幂等性(至于谓词的安全性则无需忧虑,因为其余1个命令谓词都以不安全的)。PUT、PATCH和DELETE是幂等的,而POST则不是幂等的(数次调用一个幂等的谓词的结果与仅调用一遍是一律的)。

C#基本功–之数据类型

摘自:http://www.cnblogs.com/tonney/archive/2011/03/18/1987577.html

  
在首先章大家询问了C#的输入、输出语句后,笔者那壹节重视是介绍C#的基础知识,本节的剧情也是后续章节的功底,好的启幕等于成功的3/6。在你读书完本章后,你就有丰硕的C#文化编写简单的主次了。但还无法选取持续或其他面向对象的特色。

  
本章主要针对以下多少个部份来拓展教学:

  
一、Computer是由什么来存款和储蓄所采纳的多少?

  
贰、基本数据类型有如何?

  
三、怎么样证明变量和**
赋值?**

  
四、变量和常量的区分?

  
5、不一致数据类型之间是如何转移的?

   下边,咱们现3个三个的来询问那么些题目。

  

   1、计算机是由哪些来囤积所选择的数目?

     
那几个主题素材用一句话比较含糊的牢笼,那就是:计算机使用内部存款和储蓄器来回想总计时所利用的数目。

      在现实生活中的数据有滋有味,整数、小数、字符串、字符等等,它们都类型是不均等的,所以您要想在Computer中使用那么些品种,就必须在内存中为它申请一块合适的空间。

    
那有怎样数据类型是C#能利用的吗?大家一起来看一看.

    

     
二、基本功数据**品种有啥语言,**

      首先要询问一些:C#认可的底子数据类型并未放置于C#言语中,而是内置于.net
Framework中。

     
如,在c#中扬言2个int类型的多少时,证明的莫过于是.net结构System.Int32的二个实例。那听起来就像是很深邃,但其意思隽永:那表示在语法上,可以把全部的根基数据类型看作是永葆有个别方法的类。

    
类型实际上仍存款和储蓄为中央类型。基本项目在概念上用.Net结构意味着,所以必然没有品质损失。

     上面大家共同来打听一下C#中定义的放手类型,大家将列出每种连串,以及它们的概念和相应的.net类型(CTS类型)的名号。

     
c#有一陆个约定义类型,在那之中一三个是值类型,三个是援引类型(string 和
object)

 

    1、整型

语言 1

 

   贰、浮点类型

语言 2

 

    float数据类型用于比较小的浮点数,因为它供给的精度非常低。

  
 double数据类型比float数据类型大,提供的精度也大学一年级倍(1八位)。

    如若在代码中并未有对有些非整数值(如12.3)硬编码,则编写翻译器一般假如该变量是double。

    即使想钦点该值为float,能够在其后增进字符F(或f),如:

         float f =
12.3F;

 

 3、decimal类型

语言 3

 

    decimal类型专门用于进行财务总括,使用decimal类型提供的二1九人的法子取决于用户。

   
要把数字内定为decimal类型,能够在数字的前面加上字符M或(m),如:

    decimal
d=12.30M;

 

    4、bool(布尔)类型

 语言 4

 

    五、char字符类型

语言 5

     char类型的字变量是用单引号括起来的。    
如’A’

    
若是把字符把在”A”(双引号)内,编写翻译器会把它看做是字符串,从而发生错误。

 

    陆、(Object类型和字符串类型)

语言 6

 

 三、**怎样注脚变量和赋值?**

   一、变量的定义:是指在程序的运营进度中无时无刻能够发生变化的量

    二、下边大家关系,变量在运转时个中是存在内部存款和储蓄器在那之中的,它是一个一时的寄放场合。

        
那么在内部存款和储蓄器个中,能够存放如数字、字符串、日期等等各类别型的多寡。

 

 

大家可以看一看这张图,它就把表示内存当中的一个状态。

 

简单的来说,变量就是表示内存当中的一块存储区域。

 

它会对应一个唯一的内存地址,但是我们在使用程序当时候,内存地址不好理解也不好记忆。

那么怎么办呢?

 

在日常生活当中我们都有一个名字,如"张三“、”李四“等,这些名字就是为了便于记忆。

那么同样,在程序当中,为了区别多个变量,那就需要为每个变量赋值一个简短,便于记忆的名字,

这就是变量名。

 

     3、 C#中的变量的命名是是有规则的:

        
壹)、由字母、数字或下划线”_”组成

        
2)、必须由
字母下划线”_”开头,**不能够以数字初叶**

       
 3)、不能是c#中的关键字 如:int、string、bool、Main、class等 

       
 4)、区分轻重缓急写  如:小写的a  和  大写的A 是三个变量

     

     
四、做为3个相比较好的学习者,就必须遵从一些**取名标准:**

          
1)、变量的名字要有含义,尽量用相应的意大利语命名,具备“见名知意“的作用。

                 
如:姓名   变量取名字为 name 恐怕 用拼单  xingMing,**
防止用a,b,c来进展命名。**

          
二)、防止选取单个字符作为变量名( 除在循环里面定的变量)

          
叁)、当使用多少个单词组成变量名时,应该使用**
骆驼(Camel)命名法**

                  
骆驼(Camel)命名法:第2个单词的首字母小写,其余单词的首字母大写,如:myName,myAge

           

          选择题**:以下变量命名准确的是(     )**

                  A、name、 _222*1、
9class、 public

                  B、_teacher、 void、
string、 myName

                  C、$Age、 corss、
fire、 _grade

                  D、_glass、 g23、
c_12、 my_first_2

 

 

     
5、变量的宣示和赋值

         
一)定义变量的语法:

            数据类型 **   变量名;      (概念四个年龄的变量,年龄是整数,所以变量定义如下:)**

              int         
age;        
[系统会根据数据类型,在内部存款和储蓄器中分配不相同尺寸的存款和储蓄空间]

 

            
每种数据类型前边,能够定义三个变量,如:(定义姓名、家庭地址、籍贯、民族)

                string name,address,origin,national ;

            

           二)为变量赋值语法:

               变量名 = 值;           

            
 (这里的=号表示赋值运算符,把=号右侧的值,赋值给左侧的变量名,最后以3个;[分号]结束)

              
如:年龄110周岁,姓名叫“小张”,家庭地址为“艾哈迈达巴德南坪XXX”,

                     
籍贯为“重庆”,民族为“汉”

                age = 18
;

                name = “小张” ;

                address = “加纳阿克拉南坪XXX”
;

                origin = “重庆”
;

                national = “汉” ;

 

 四、变量和常量的界别

         变量:是指在程序的运作进度中时刻能够产生变化的量

        常量:是指在先后在运作进程中不会产生变化的变量

         

          常量的特点:

                   一、必须在注脚是赋值

                   2、无法在在程序运维时,给常量赋值

                   三、常量是静态的。不必须(实际上,是不相同意)在常量注明中包蕴修饰符static 

        

 五、差异数据类型之间是怎么样转移的

       在C#中数据类型调换分为三种:一)隐式[又叫自动]类型调换     二)显式[又叫强制]类型转变

           举个大致例子:

           飞机场里面停飞机,这是本来,大家把那种称为隐式[又叫自动]类型转换**

   

           那如果大家掉转看壹看,飞机内部装飞机场,那些在大家实在生活中,感到那是依据不容许的,

           可是程序恐怕实现那或多或少,大家把那种称为显式[又叫强制]类型转换**

 

      
在C#中数据类型调换分为三种:一)隐式[又叫自动]类型调换     2)显式[又叫强制]类型调换

           举个差不离例子:

           飞机场里面停飞机,那是理所当然,大家把那种称为隐式[又叫自动]类型转变**

   

           那若是大家反过来看1看,飞机内部装飞机场,那么些在我们其实生活中,感到那是依照不也许的,

           不过程序能够产生这点,大家把那种称为显式[又叫强制]类型转变**

 

          
double和int之间正是(飞机场与飞机)那种涉及,大家得以如此敞亮,double的取值范围比int要大得多

          
所以double能够装得下int :

**          int a=1234;   


**          double b=a;  
系统会把a整型变量的值赋值给double变量b.那正是
隐式[又叫自动]类型转变**

 

        
那反过来:

         double
a=1234;

         int b=a;       
//系统一编写译时会报错,如图:

         
语言 7

**        


**           那怎么开始展览强制转变呢?c#提供了充裕简便的措施,如:


**          double
a=1234;**

          int b=(int)a;      //那样就威吓把double类型,转变为int类型

 

**        
最终,再介绍一下,其余数据类型之间的退换(
一、字符串调换为任何品类   二、大四档案的次序之间的改换)**

         一)、字符串转变为别的品类       

       语法:

        XX.Parse(字符串);        
那里的xx代表的如:double,int,bool等

        
举个例证来说Bellamy(Bellamy)下:

          string
strValue=”1贰三.四伍”;    
//那是二个字符串,时面包车型客车值是”1二叁.肆伍”

         
现要把它调换来小数类型,就足以行使double.Parse();来展开调换

         double dValue=double.Parse(strValue);

 

       贰)、大肆档案的次序之间的转变**

        语法:     

        
Convert.ToXX(任何类型);

 

         如:把一个布尔类型转换为整型

                  bool a = true;
                  int b = Convert.ToInt16(a);
                
Console.WriteLine(“转变后的结果是:”+b); 
//转变后的结果是:一

 

查询

小编们供给八个查询:GetInventoryItemsGetInventoryItemDetails。那里大家将由此两个GET方法/api/InventoryItem/api/InventoryItem/{id}暴表露那多个查询成效。

GetInventoryItems艺术能够获得仅包蕴了货物名称Id的一个列表,它会依据ACCEPT头决定回去JSON或是XML(ASP.NET
Web
API能够接济那一效益)。假使有个别财富符合于缓存,那么全体的GET请求都有希望回到缓存数据。GetInventoryItems返回InventoryItemListDataCollection用作出口信息。即使能够透过数量内容的哈希生成ETag,可是那里大家选用将列表中每一项的Id名称开始展览哈希后获取的结果作为ETag再次来到给客户端(举例浏览器)。客户端能够挑选将财富缓存起来,并对准ETag使用If-Non-Match进展标准请求。大家选取将能源的max-age设为0,由此客户端的GET会始终使用规则请求,可是也足以选用设置一个人工的逾期时间。

GET /api/InventoryItem HTTP/1.1 
Accept:application/json, text/plain, */* 
Accept-Encoding:gzip,deflate,sdch 
If-None-Match:"LdHipfxR7BsfBI3hwqt2BLsno8ic98KmrIA1y67Nnw4="

重回结果

HTTP/1.1 304 Not Modified 
ETag: "LdHipfxR7BsfBI3hwqt2BLsno8ic98KmrIA1y67Nnw4="

GetInventoryItemDetails方法会重临有些仓库储存货色的细节,包罗IdNameCurrentCount品质,最终一项属性记录了当下的仓库储存数量。尽管其间领域的读取模型(read
model)包涵了版本号,但借使将有个别数值类型的版本号直接当做ETag会时有产生安全性难点,因为客户端能够随意地猜出下一个数值。由此,大家选择了利用高档加密标准(AES)对版本号举行加密后,作为InventoryItemDetails方法的ETag输出。

为各个操作都重新落成ETag对于API层来讲多少担负过重,因而我们定义了三个IConcurrencyAware接口:

public interface IConcurrencyAware 
{ 
    string ConcurrencyVersion { get; set; } 
}

每一个帮忙ETag的输出模型都要得以达成那几个接口,当API层看到有个别输出模型支撑那一个接口时,就会读取版本号并设置ETag值。另1方面,当API层对条件式GET请求进行响应时,会将扭转的ETag与客户端在If-None-Match头中传入的值举办相比。全体这几个操作都得以透过2个独门的大局filter达成:ConcurrencyAwareFilter

急需专注的是,增多、删除或然重命名有些仓库储存货色时应该使物品列表的缓存失效。请看上边包车型客车例证(条件式GET请求的逻辑是在浏览器端完毕的,不须要专门编写代码完毕):

GET /api/InventoryItem HTTP/1.1 
If-None-Match:"CWtdfNImBWZDyaPj4UjiQr/OrCDIpmjVhwp8Zjy+Ok0="

再次来到结果是2个状态码为200的完好响应,并且包涵了一个新的ETag值:

HTTP/1.1 200 OK 
Cache-Control:max-age=0, private 
Content-Length:68 
ETag:"0O/961NRFDiIwvl66T1057MG4jjLaxDBZaZHD9EGeks=" 
Content-Type:application/json; charset=utf-8; domain-
model=InventoryItemListDataCollection; version=1.0.0.0; 
format=application%2fjson; schema=application%2fjson; is-text=true 
...

请留意Content-Type头包涵了额外的参数,那是对此“传播媒介类型的七种等第”(可能简称5LMT)概念的1种完成,那种方法不是将装有音信都塞到贰个单独的令牌(token)中,而是接纳分裂的参数来发挥对用户有用的例外级其他数额,能够抒发不一样等级的有用音信。下文种对那几个焦点做进一步的座谈。

结论

非但经过一套REST
API揭发CQPAJEROS是恐怕的,而且HTTP语义的丰裕性也使得大家能够在它的功底上编写制定壹套流畅而使得的API。整个流程蕴含创立三个由命令和查询(输入输出音信)组成的当众领域,以及能够管理并发和缓存的种种能源。其余,大家还必要将里面领域的查询和指令映射为HTTP谓词,并且应用景况码以表现情状转变和万分。使用5LMT将力促创立完全RESTful,而不是远程过程调用风格的能源。全部这个都得以由此二个异常的小但能够运作的原型应用进行突显,该原型是通过ASP.NET
Web API和AngularJS完结的。

CreateInventoryItemCommand

从CRUD范式的角度来讲,CreateInventoryItemCommand很当然地适用于POST方法。(那里只展现首要的头新闻)

POST /api/InventoryItem HTTP/1.1 
Content-Type:application/json;domain-model=CreateInventoryItemCommand  

{"name": "CQRS Book"}

再次来到的响应如下:

HTTP/1.1 202 Accepted 
Location: http://localhost/SimpleCQRS.Api/api/InventoryItem/
109712b9-c3d5-4948-9947-b07382f9c8d9

该操作将要location头音讯中回到那几个将被创设的仓库储存货物(因为有着操作都以异步实践的)的U普拉多L地址。

创设壹套上层的REST API

若是您赞成于先去感受一下最后的贯彻,能够在此处看一下3个当下(一时半刻性)可运行的原型。大家鼓励你使用fiddler或许浏览器自带的开辟工具去检查一下这一个大致的演示中的HTTP请求。在GitHub上得以找到包涵那套API和二个焦点的Angular应用的源代码。可是大家依旧要重申,它的兑现情势和动用的才具并非关键所在,读者更应有关注于统一筹算方法及HTTP的呈现。

本文在此提议并为读者体现一种为CQRubiconS系统创制一套RESTful
API的秘技。那种方法结合了HTTP的语义、REST
API基于财富的作风,并能够管理分布式总括的少数难题,比方最后1致性和并发性。

小编们在将下局地审阅m-r的领域模型,随后对有关性子的API设计开始展览局地搜求。最终,大家将对部分所做的抉择打开钻探,并且研究一些RESTful
m-r的概念和辩白内容。

RenameInventoryItemCommand

RenameInventoryItemCommand比起其它命令来讲更有趣一点。首先,重命名1个仓库储存货色也等于举办修改,由此使用PUT谓词是最合适的。另一方面,假诺您正在重命名有些货物时,你的同事也在尝试将其重命名称叫另三个名字的话会什么呢?那就是一个涌出难题。HTTP通过If-Unmodified-SinceIf-Match提供了对能源实行并发修改时的保卫安全机制。因为我们运用了ETag,因此就相应地安装If-Match

PUT /api/InventoryItem/f2b75f21-001a-4eed-b8f3-35bf5e4e9b0d HTTP/1.1 
Content-Type:application/json;domain-model=RenameInventoryItemCommand 
If-Match:"DL1IsUoH709K+N5TXFzlQeQI5arO8r/U0SzXcRhuXLc="  

{"newName": "CQRS Book 1"}

AngularJs的controller会传递ETag值,并传到模型中,之后在标准式PUT请求时开始展览利用。如你所见,ETag的值仅仅是对世界模型中版本号的1种表现,但大家对其张开加密以知足HTTP规格的内需。服务端获取到这几个值之后进展解密并复苏成版本号的数值。假设版本号不相称,领域模型就会抛出三个ConcurrencyException异常,在API层的ConcurrencyExceptionFilterAttribute类捕获到这些10分之后,会以HTTP语义的章程呈现该尤其。

HTTP/1.1 412 Precondition Failed

本条例子很好地注解了HTTP的面世怎么着与CQ奥迪Q5S的出现检查体制相结合。

一声令下和询问义务分开(CQXC90S)是由格雷戈Young提出的一种将系统的读(查询)、写(命令)操作分离为二种独立子系统的架构格局。命令日常是异步推行的,并储存在贰个事务型数据库中,而读操作则平日是终极一致的,并且数据出自于解正规化的视图。

CheckInItemsToInventoryCommand和RemoveItemsFromInventoryCommand

那三个指令就更是有趣了。我们将往仓库储存中参预或删除一些物料。从某地方而言,那种操作是对库存货物的多寡进行立异,因而能够将其落实为2个PUT(大概PATCH更合适)方法。但因为那多少个指令并非幂等(比方说,调用CheckInItemsToInventoryCommand四次应该加上五回仓库储存),由此最符合的谓词实际上是POST。

客户端就要Content-Type头音信中的参数中安装领域模型的称号,就像我们前边所见的1律。

POST /api/InventoryItem/f2b75f21-001a-4eed-b8f3-35bf5e4e9b0d HTTP/1.1 
Content-Type:application/json;domain-model=CheckInItemsToInventoryCommand  

{"count": "230"}

归来的响应是同等的:

HTTP/1.1 202 Accepted

至于我

语言 8Ali Kheyrollahi
是一位化解方案架构师、作者、博主、开源软件的撰稿人和进献者,方今供职于伦敦的一家大型电子商务集团。他对HTTP、Web
API、REST、DDD和概念模型抱有壮大的欢呼雀跃。而在拍卖实际的事务难点上又百折不挠实用性。他在那1行已有12年以上的经验,并在多个杰出企业专门的学业过。他对此计算机视觉和机械和工具学习世界有着抓牢的兴趣,并且已经公布了多篇故事集。在在此之前,他曾是一名医师,并作为一名非专科医务卫生人员专门的学业了五年。能够在此地找到他的博客,别的她在twitter上也格外活跃,能够经过@aliostad关切他。

翻开原来的作品地址:Exposing CQRS Through a RESTful
API

此外我们还提供了1套原型API,它确立于GregYoung编写的m-r
CQ宝马X五S原型之上,后者也被号称SimplestPossibleThing。m-r能够以为是CQOdysseyS原型的事实标准,它激情了数不尽团队利用并创立CQENCORES系统。就算那几个m-r原型很简短,但它曾经可以显得在切实世界中动用RESTful
CQ大切诺基S系统的一些机遇和挑衅了。

m-r领域

m-r模型是2个通过简化的仓库储存管理种类的圈子模型,你能够成立新库存货品(假如它是某系列型的出品),重命名或注销激活(即逻辑删除)它们。被裁撤激活的物料将不再为用户所见,而富有移动的物料都足以被拿走,并且能够见到各样物品的持有细节。你也可以扩大或收缩这么些仓库储存物品,钦定所进入或回落的物料数量。换句话说,在建立仓库储存量之后,就能够起来应用那个种类了。

用户将因此共同的查询来查阅货色列表或是物品细节,对于货物境况的更换将透过命令来贯彻。在实际世界中,命令应该是异步推行的,但出于代码中运用了内部存款和储蓄器中的轩然大波总线(伊夫nt
Bus)及事件管理函数,因而在最终得以达成中命令都以同台实践的。

语言 9

m-r模型达成了CQPAJEROS:命令和询问被分级存款和储蓄在区别的地点,并且各自由系统中全然两样的一些进行拍卖。

除外CQ科雷傲S之外,m-r也接纳了事件源自(伊芙nt
Sourcing)作为它的持久化学工业机械制。在那种方式中,对于世界模型的改造会被捕获为壹密密麻麻的事件,那几个事件会鲁人持竿它们被调用的顺序存款和储蓄起来。为了获取有个别模型的当前场合,需求将全部事件依据它们发出的相继举行重放。换句话说,模型中实体的情形消息是不会被持久化的。比方来讲,假诺大家创造了一个仓库储存物品,随后将它重命名四遍,那么大家将会拿走八个InventoryItemCreated事件和四个InventoryItemRenamed事件,那一个事件都会被封存在事变存款和储蓄(伊芙nt
Store)中。

事件是接贰连3的,并且每一个事件都富含一个版本号,用以在并发时举行自己研究。例如来讲,假诺有个别仓库储存货色在本子2的根底上海展览中心开重命名,但恰恰有另三个重命名发生在同2个货物上,并使它的目前版本变为三,那么那种状态就会导致出现格外。

命令与世界事件司空见惯是一定的关联,当调用了某些命令之后,领域模型会倡导并积存八个轩然大波。领域事件是事件源自的基业,它和跨七个境界上下文(bounded
context)的风浪不一样,往往粒度越来越细,并且只包涵所需的矮小数量的新闻。由此,它并不是一个相符于在差别的境界上下文之间打开集成的工具。除了选取三个经过内的事件总线之外,m-r还用到了一个内部存款和储蓄器中的风浪存储。那一个蕴藏本质便是1个哈希表,它使用模型的id作为键,并且不止追踪模型中产生的其它交事务件。

如欲领悟CQ福睿斯S和事件起点的更多音讯,你能够翻阅格雷戈Young的那本Mini书

讨论

那一局地将详细讲述有个别理论概念,以及我们的支配中一些比较不方便,或然可能引起争议的片段。

HTTP的别样地方

贯彻HTTP的部分别的方面也会推动一些功利,HEAD也是一个生死攸关的谓词,它的响应结果和GET方法一样,但再次回到的响应体中不包涵其余内容。大家为富有GET能源都达成了HEAD谓词,比如:

HEAD /api/InventoryItem HTTP/1.1 
Accept:application/json, text/plain, */* 
Accept-Encoding:gzip,deflate,sdch

将返回

HTTP/1.1 200 OK 

ETag: "LdHipfxR7BsfBI3hwqt2BLsno8ic98KmrIA1y67Nnw4="

具体在促成人中学会将HEAD请求转向给GET方法的管理函数,而框架本人会在结尾担负移除重临的剧情。那1一日千里达成都是活动触发的,因而在响应中能够正确地赢得ETag。

另3个急需贯彻的第三谓词是OPTIONS,这些谓词能够用于生成API文书档案,不过我们这里只是简短的回到该财富支撑的兼具谓词:

OPTIONS /api/InventoryItem/f2b75f21-001a-4eed-b8f3-35bf5e4e9b0d HTTP/1.1

它将再次来到如下内容:

HTTP/1.1 200 OK 
Allow: GET,POST,OPTIONS,HEAD,DELETE,PUT 
Content-Length: 46 
Content-Type: application/json; charset=utf-8; domain-model=String%5b%5d; version=4.0.0.0; 
format=application%2fjson; schema=application%2fjson; is-text=true  

["GET","POST","OPTIONS","HEAD","DELETE","PUT"]

请小心,响应中的Allow头对于OPTIONS请求来讲是必须的。可是HTTP规格本人并从未点名OPTIONS响应体中实际写法,由此我们就将同意的谓词作者为2个字符串数组重返(注意,在domain-model参数中的String[]是经过UrlEncoded方法编码的结果)。能够接纳这几个谓词生成符合各类schema和语言需要的API文书档案。

除开这一个点子之外的别的调用都会回到一个办法未找到(method not
found)
抑或40五状态码,ASP.NET Web API本人已经完结了这一职能:

PUT /api/InventoryItem HTTP/1.1  

{}

它将赶回:

HTTP/1.1 405 Method Not Allowed 
Allow: POST,GET,HEAD,OPTIONS  

{"message":"Http Method not supported"}
可选的出现检查

在m-r最初的兑现中,全数命令(除了CreateInventoryItemCommand,它已经隐式地包括了值为0的版本号)都含有二个平头型的CurrentVersion字段。而以此本子旅长它们修改为可选的(即C#中的可空类型)。

在1边,服务端应该负担保险小编状态的完整性。因而它无法、也不该借助于客户端所提供的版本号。并发检查是用作一个表征提须要客户端的,而不是服务端用以保障模型完整性的体制。假设客户端关怀并发行为,那它就能够采取性地发送版本号,这曾经通过在ETag中的加密音讯提必要它们了。要牢记的是,并发检查与服务端的轩然大波版本号是差异的定义,后者是服务端的内部贯彻机制。

1边,对于一些操作来讲,并发检查是向来不意思的。举个例子来讲,假诺五个客户端在同一时半刻间(调用CheckInItemsToInventoryCommand方式)加多了十八个仓库储存货色,并且它们都有着版本号n,那么内部有3个指令就会停业,但那种失利是不要求的,因为我们真的需求增多四十多个物品。那种主题素材在高访问量的情状下会被加大。想象一下,假如大气的用户涌入亚马逊(Amazon)网址去购买哈利Porter的新型1期,在大多数状态下她们都会遇上并发难点。

在HTTP中推行PUT(和PATCH)操作时会以为出现是三个可选的反省,那或多或少不要偶然。固然出现检查能够异步实践,但大家供给全力以赴确定保证它必须一齐实践,因而当大家回去状态码20二(已接受)时,就意味着服务端已经确定了从未有过出现争持境况的产生。

DeactivateInventoryItemCommand

仿佛前文所述,打消激活仓库储存物品就表示2回逻辑删除。此外,删除操作是幂等的,因为屡屡去除2个库存货色的法力和叁次删除是均等的。因而大家将选取DELETE选项作为撤消激活某些货物的办法(该办法包蕴三个空的方法体)。

DELETE /api/InventoryItem/f2b75f21-001a-4eed-b8f3-35bf5e4e9b0d HTTP/1.1 
Content-Type:application/json;domain-model=DeactivateInventoryItemCommand  

{}

返回的响应如下:

HTTP/1.1 202 Accepted

就算也足以在方法体中传送id,但在URubiconL中一度提供了id音信。DeactivateInventoryItemCommand构造函数的绝无仅有职务是天经地义地安装domain-model那些参数。

媒体类型的四种品级(5LMT)和创制新的传播媒介类型

在社区里常见的1种做法是创办新的媒体类型,平时号称制作新的传播媒介类型。举例来说:

Content-Type:application/vnd.InventoryItemListDataCollection.1.0.0.0+json;

那种利用格外的法子意味着有些媒体类型的子类型已经化为了壹种通用的实践(已经实际成为一种约定了),它将子系统一分配解为一些特定的、或许是正统的因素,并经过+号连接在同步。已经某个经过登记的媒体类型应用了那种约定,举个例子application/rss+xmlapplication/atom+xml。那八个示范处于媒体类型等第中的第二品级(或然叫做schema等第),而application/xml则处于第3等第(format品级)。某种意义上说,application/atom+xml即是壹种application/xml项目,它们利用同样的format,而前者还指明了会选择ATOM
schema。

即使那壹约定会在现在版本的HTTP规格中收获承认,但它从未缓慢解决媒体类型不断增加的难点。首先,使用其余未注册的媒体类型都是HTTP规格所不提倡的,使用上述项目标Content-Type值也是如出一辙。实际上,假使大家须求在具有API中为七个例印媒体级其旁人身自由组合都登记壹种媒体类型,那网络号码分配局(IANA)大概供给动员第一次全国代表大会批判人去专门从事那个层面巨大的任务了。另一方面,许多客户端系统使用基于dictionary的媒体类型去处理那种请求,它们将不可见应付新创立的传播媒介类型。

之所以使用伍LMT能够允许现存的客户端继续遵守从前的格局健康干活,而更上进的客户端则足以选择越来越高等别的信息,它们都以作为独立的实体提供的。

通过1个精晓的园地有限援助内部领域是关键所在

将服务端的里边贯彻举行抽象对客户端的话是可怜关键的。就如此前所述,为比较小的世界所开创的公然领域和中间领域会比较相似,但不怕是在m-r那几个示例中,大家也不可见将内部领域直接暴流露来,而必须创制3个独自的模子,它显现了客户端能够收到和相互的信息

我们还应该将公开领域文书档案化,并显现给客户端。那1端的拓展值得关心,因为早已有种种差异的形式和举行开头呈现水面了(从WADL到Swagger、RAML和RestDown等等)。

大庭广众领域的组织

对此这么些API层来说,最要害的权力和责任是将底层的领域建立模型为能源,并因而HTTP语义暴表露来。在这一个进度中,API层将创制3个集体领域,它由能源(以及它们的绝无仅有标志符->ULANDL)以及输入和输出的音信所组成。底层的世界越轻松,那个公开领域和底部领域的貌似程度就越高。

(单击图片以推广)

语言 10

在这几个例子中,大家创造的公开领域与底层的小圈子照旧相比较一般的,但不怕是那种容易的天地,大家也不可见从来将底层的园地暴表露来:那大概导致领域的中间贯彻被泄漏出来,而且世界里面也不确定带有API层所需的方方面面质量。比如说,全部的其中命令都会用叁个整数来代表并发时所需的版本号,而在当众领域中则用字符串意味着这些性格。我们稍后将会采取那脾天性作为ETag,而依靠HTTP规格供给,ETag必须是不透明的。

简短来说,大家所创办的明白领域表现了里面包车型大巴小圈子类,但又有差别。那种公然领域平常被称作1个视图模型(Vide
Model)。那个术语并不太规范,因为那种表明情势以为上对公开领域有个别排外,将它视为一种“哑”模型,由此大家赞成于采取二个新术语“输出模型”(output
model)。它将被使用到输入和输出音信中(命令和出口模型)。

资源

大家很当然地想到应该有贰个InventoryItem财富,由此大家将世界中的那一个单根实体揭露为贰个单独的能源,能够用/api/InventoryItem方便地进行表示。每种仓库储存货色将用/api/InventoryItem/{id}开始展览表示,m-r使用了全局唯壹标记符(GUID)作为Id。

使用这些独自的根对象就足以全体的展现大家的小圈子了。还有1种艺术是使用/api/InventoryItem/{id}/Stock本条能源作为丰盛和删除仓库储存量(即签入或移除物品)的措施。从实质上说它们从不什么高下之分,无非是哪一类办法能够更加好地显现能源而已。由于第壹种艺术越来越方便,由此我们就应用那种措施。

(单击图片以拓宽)

语言 11

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图