00:13
大家好,我是今天的讲师Nick。今天我们来讲一下构言之web server。咱去嗯认识一下web server,以及去嗯看一下怎么去使用它。然后一步一步的深入去了解web server。好,今天的一个主要内容啊,一个是web server的一个介绍,第二个呢,是一个基本语法的一个讲解。第三点呢,是我们做一个递进式的代码实践。第四点呢,就是说我们去做一个restful API的一个介绍,第五个呢,我们去做一个restful。的一个代码实践。
01:00
我们看一下我们今天需要用到的一些文档信息啊,一个是嗯,Go的一个net http包的一个文档啊,这咱先打开。第二个呢,是。Http root的一个源码,也是一个第三方的一个。Http root。你去打开打了。第三个呢,是HTTP的一个协议文档。嗯,这个打不打开没什么太大关系啊,这个我们打开可能也看不懂。呃,第四个呢,是rest API的一个文档是一个。嗯,网文咱。就不打开了啊。
02:01
咱来看一下咱的这些文档啊。好,咱文档呢,先打开这咱。继续讲我们接下来的东西。好,那我们接下来讲什么呢?首先,什么是外部私网?这是我。从维基百科上啊,百度百科也好,维基百科也好,咱去找到的这么一个资料啊,说什么什么是一个web搜呢,Web搜索是一个通过HTTP协议处理web请求的计算机系统。咱一定要注意啊,它是一个计算机系统。它不仅仅是一个web,不仅仅只是HTP协议,它是基于一个HTP协议处理web请求的计算机系统,说明它包括一个serve端。HTTP协议呢?在osi就是开放式系统互联通讯参考模型这种网络体系结构中,是基于TC pip之上的七层应用的协议。
03:13
全称叫做超文本传输协议。就是说HTTP传输的都是文本字符。只是这些字符呢,是有规则的排列。这字符的排列规则就是一种约定,也就是协议,这个协议还有一个专门的描述文档,就是叫做RFC22616,咱看一下这个文档啊。你看一下。协议文档。啊,这是它的一个。HTTP的一个协议文档,咱看啊,这个基本上。
04:03
没几个人能看得懂。这是一个相当专业的一个文档啊,咱就不多说了啊。咱继续讲,接下来讲咱的。好,接下来就是说,对于HTTP协议啊,无论是请求还是响应传出的消息体都可以分为两个部分。比如请求地址。编码格式。啊,分为两个部分,一个是HTTP的一个头部,咱通常叫做hide。还有一个是HTTP的body头部描述,一般是和业务无关,但是与传输相关的一些信息啊,比如说请求地址啊。编码格式啊,缓存时长啊,Bo里面那主要是描述的是与业务相关的一些信息,比如说我们的字段啊,然后响应response里头相应的一个返回结果啊,那些都都是跟我们业务相关的,那web service web service的本质呢,实际上就是。
05:14
接收解析HTTP请求传输的文本字符。理解这些文本字符的指令,然后进行计算,再将返回值组织成HTTP响应的文本字符,通过TCP网络传输回去。啊,这是大概的一个概念描述。那么我们接下来看一下一个请求流程示意图啊,咱。假设有一个用户。需要修改自己的一个用户信息是吧,然后他在浏览器上修改自己用户信息,然后浏览器通过HTTP请求到服务器。服务器呢?通过访问数据库,把数据写到DBDB,然后返回服务器一个处理结果。
06:03
然后服务器再通过HTTP响应去返回给浏览器,这就是一个web请求的一个简单的示意图。接下来我们来了解一下。HD头部和HT body是什么啊?这我截了一张图啊,大家看一下。嗯。咱就以网页来说吧哈,咱来打开一个网页。咱看到的开发者啊,咱来选择这个网络最下面啊。网络下面这个请求啊,咱顶一下。
07:05
刷新一下。看到没有,这就是一个。这就是一个HTTP的一个请求,看到没有。请求头,响应头。这都是按照一定的规则去组合的这么一个呃,文本格式。好,那么我们了解了,呃,Web server的一个大概情况啊,那我们接下来去做什么呢?我们去,嗯。通过代码去实践。咱看咱在go语言怎么样去创建web server,创建文件server啊。
08:02
好,咱的第一个样例,一个静态文件服务啊,静态文件服务利利益。咱看一下啊。嗯,咱就直接上代码。好,静态文件负一咱看一下。有没有发现起个HTTP是我非常的简单。直接HTTP啊,这是一个,嗯。够浪常用的一个包啊,http.and server。他就能够去监听一个服务鉴定这个地址啊,这冒号8080啊嗯,省确省的IP,那默认就是本机。然后HTTP。去建一个文件serve网啊,这咱就是说起一个静态文件服务器,咱看一下它的一个语法结构啊,你看listen啊,Listen survey,他接受什么接受一个。
09:12
地址和一个。处理程序加handle。咱看一下file server file server它返回的什么,它返回的也是一个。Handler。技术一个文件。文件系统啊。看什么file system,什么是file system?只要实现了open这个接口的,那都是file system啊。那么我们来。运行一下这个。简单的一个文件设网,咱看他是什么样一个情况。看咱指定的目录是D盘的temp啊,咱来运行一下。
10:15
项目都稳定起来了啊,我们的扶起来了。服务起来呢,我们来。打开一下啊。WAHO8080开没有。他就能够看到我们这个目录下的一些内容,我我来看一下啊。我的地盘。地盘。TP下。是不是?我们这些文件内容。我们点进去。这里头是空的。Images啊,你看images里头有一个TXT。
11:03
咱看下对不对啊。Images里头应该有TXT。但是还有个点黑点的文件并没有显示啊。好,咱再看一下其他文件目录下有没有文件啊,是没有的。这大概就是一个最简单的一个,呃,文件社保。
12:11
大家去想一下,为什么这个文件搜索没有显示这个点黑等的。这个文件啊,咱咱再新建一个啊,新建一个,再新建一个其他的文件啊。这叫做。TXT。然后我们再来看一下啊。Image。啊,都出来了啊是没有刷新。好,所有文件都在那就没有问题啊。好,我们的最简单的一个,呃。
13:04
文件设啊,咱已经看了啊,咱点进去看一下它,简单的看一下它源码。他其实就是把这个处理程序啊,赋值改这里头的一个是否对象了,咱看一下里头一个,呃,内审显示什么东西啊。大家可以看一看啊。基本上判断。如果是server停了啊,停了就直接返回了一个server close。如果没有停,那么就把address赋值啊,做一个HTTP,看到没有,然后net去listen一个TCP的一个地址。
14:07
然后再用四五去打开这个连接啊,大概是这么一个情况。好,我们第一个例子呢,讲完了,咱再接着讲第二个啊,这是我们接着一个简单的。文件设网。那么我们的用力用力二讲什么的呢?用例二其实就是说在原有的基础上去改变。他的一个访问目录。咱看一下啊。用力啊,我们已经写好了啊。跟之前不一样的地方就是在这里啊,咱的hdlo。需要去访问这个目录啊,这个temp files啊,咱给它定义这么一个路径。
15:02
然后这个路径呢。就跟我们平时访问接口一样。他就是。一个虚拟,虚拟,虚拟直下。然后呢,HTP。啊,咱看一下这是干什么的,他的意思呢,就是说。如果我访问的路径和我指定的这个perfect不一致。那么他就会。报404。就认为它是不存在的。咱看一下啊。俺把原来那个给。啊,停掉。咱去运行。用力二。那我们用例啊,我们再来访问一下。
16:02
看到404了。因为我们没有用这个。虚拟的。路进来访问啊。我们看一下啊。行,我们给他改一下。用指定这个路径来访问。好,这样就可以了,大家注意一下,这里指定是什么,就是什么也有杠就有杠。啊,自动补全了。刷新一下。啊,有没有杠没有关系啊。那么同样可以访问到这些目录,看没有?文件都是空文件啊。
17:01
咱给他改一下啊。咱比如说叫啥呢。我给它改成不是啊FIVE1啊,怎样FIVE1。好,这样的话,他的handle的pattern是不是跟这个perfect是不一致了。我们重新编译,嗯,重新运行。好,不一致了。啊,我们这敲错了啊,我们。TEMP1啊。看到没有?他不一致,那就不行,那必须。必须一致啊,这个地方。后面这个就是刚才讲过了啊,这个就是嗯,去加载一个嗯,Handle。
18:06
做一个发社保来。第二个我们讲完了,我们讲第三个例子啊。第三个例子是实现一个不包含点开头的文件的静态服务。来看一下啊。来三个例子。好,咱看咱的main函数啊。半函数去使用了这么一个结构体。这么一个结构里,里头呢,接一个file system file system,咱在上一个例子咱也看到了啊,就是。
19:01
这个HTP点,嗯。Di。它就会返回一个file system。急,就是去打开了一个文件啊,打开了一个文件夹。那么这个这个结构体又是什么意思呢?你看啊,这个结构体,其实呢,这个结构体是我们自己定义的。他内心的一个face是什么?啊,结构体。然后呢,还有一个。咋样啊?
20:01
都。有一个file的结构体啊,内嵌一个HTP的http file一个呃。你给face。你看啊,这个do。To fire,黑fire去使重写啊,这个地方应该是重写,重写了这个呃,读取目录的这么一个呃方法。我们知道就是说嗯,我们借口去通过,呃,通过实现接口或者是重写。
21:04
重写接口的一些实现啊。我们在调用的时候,它就会用到这么最新的一个方法啊,这个地方,所以相当于它这是嗯。重写来file这个read啊,Read。然后这里面做了什么处理呢?然后去做了一些文件路径的判断。啊,咱这里看啊,看这个文件名的一个pre前缀。是不是点啊。如果不是点啊,然后就给这个。这个给这个。数组去end一个fire对象啊,来看啊,这是这是比较关键的一个地方啊。
22:02
其实这个例子的一个目的在说明什么呢?就是说为什么是以点开头的呢?就是在。通常一点开头的文件啊,就是说我们的一个隐藏文件都会是一点开头啊,尤其是在呃Linux环境下啊,在Windows可能点开头并并不意味着什么啊,但是在Linux下的点开头啊,都是隐藏文件。但是如果说我们去,嗯,用,比如说用get啊,用idea去。去生嗯,去打开项目啊去呃,初始化项目啊,它生成一个点开头的文件,通常也会是一个隐藏文件,所以这个地方其实就是说不要读取隐藏文件出来了啊,大概就这么一个逻辑。然后我们去运行一下这个例子啊。
23:12
下这个。好,我们再来访问一下。看一下我们的一个访问路径啊。啊,斜杠。大家看到了,这里有一个点黑子的文件夹啊,它是可以访问到的。说明我们这个程序还是,嗯,不够完善的啊。但是呢,这个。文件。文件夹下的文件啊,点黑的啊,已经隐藏掉了再看。
24:09
这就是文件服务的一个三个例子啊,咱回头大家啊,自己去研究研究,琢磨琢磨。看到底是怎么一回事。看一下这些,呃,继承关系啊。好,文件系统啊,文件server啊,File server我们讲完了,讲完了之后呢,我们去讲我们的今天的一个比较重要的一个部分,就是web server的一个httv web server的一个实现方案啊。大家看了一个我们刚才的一个文件系统的一个实现方案,大家应该也知道这里头去实现这个东西,其实嗯。挺简单的。
25:00
没有我们想象那么复杂。好,咱卖咱就不看文档了啊,咱直接看代码。咱先实现一个最简单的一个web啊。的逻辑是吧,接受一个地址和一个handle。但是这个地方你看啊,它默认是没有接触handle罗的,但是他在上面只定了一个HTTP。电焊了。好,咱去看一下这个igtb.handle它里头是怎么做的。Car。他其实给一个默认的呃,Server。
26:01
多路复用的一个路由器,End了这个handler。哎呀,说我多路不用。他这里指定了一个读写锁,然后呢,这里是有一个map string一个实体啊。啊,一个输入。其实就是一个map结构给这个,呃。防止。防止有什么呢,防止。防止并发啊,因为map它默认是一个不安全的啊,所以我们是需要有这么一个,呃,读写锁在这里给它做控制。你看给。给这个路由去附加一个呃,处理程序的时候啊,它一进来先去给这个呃路由上锁,然后里头去给它解锁。
27:08
大家注意一下这个上锁解锁啊,它这个是呃成对出现的。就是有一个上锁,就必须有一个解锁。它并不能,并不像我们平时程序设计说可能,嗯,我只允许一次上锁,但可以多次解锁,我没有锁的情况下我再解锁啊,它可能。不会有问题,但是这里啊够圆,这个地方就是我上锁了,我就必须有解锁,我解锁那么就必须在前面有上锁,不然他就会拍那个。这个地方大家注意一下啊,他特别容易搞混啊,面试的时候也经常会问到这种问题。好,咱看下啊。你看他去判断这个集合里头有没有这么一个路径啊。
28:02
如果有。那直接panic了哈。如果没有你看啊,他就给他。做了一个副职,然后给他。写进去了,就大概就这么一个情况啊。好,这个地方呢,这是我们最简单的一个serve啊,最简单的一个serve,它的一个处理程序是什么呢。处理程序是打印一个h.N啊看啊h.N。恩加加。看到没有,这个地方其实也用到了锁,这里用的一个锁呢,是一个互斥锁。跟读写手不一样。
29:06
护之锁,那相当于是这里一个请求是加护之锁主要是为了什么,就是说防止一个并发。可能就是啊,我一个。N啊,如果我没有加复制锁,那么可能存在的情况是,我多个请求过来,刚好在同一时刻,大家访问到的N是一样的,所以打印出来的也是一样的。但事实上。他的请求数是变了的,比如十个人请求,十个人同同时请求,那我没有加速的情况下。那么大家都打出来11了。但我加锁了。那不好意思。啊,十个人先,谁先获得到了锁,那谁去打印这个N,然后用完之后啊去给他解锁。这样的话就会导致的一个问题的,就会使大家的一个并发反应过来之后是一个顺序执行。
30:01
或者说是挨个之前啊,他可能进来的是乱序的,但是谁先获得锁谁就用,用完之后解锁,另外一个人才会用。在没解锁之前啊,它是一个阻塞,阻塞状态。然后大家思考一下啊,这个护士锁啊,和那个读写锁有什么不一样啊。好,这个地方我们来运行一下我们的例子啊,今天。
31:18
哎呀,我们不断的刷啊,它就会顺序在增加。好,我们这个例子就讲完了,这是一个啊,最简单的一个。我不是我。我们再看第二个实现方案。
32:03
好,第二个实现八啊,你看一下。第二个实现方案,大家看一下啊,咱的第一个实现方案它呃。它是http.handle。第二个实现方案是http.handle fun。处理函数了。其他都是一样的,我们来看一下啊,看这个憨funk啊到哪里去了。看到没有,它其实也是给这个默认的路,嗯,默认的这个路由器去。附加这么一个处理处理程序。没有。
33:01
一样的走到了这个位置来了,看到没有?所以他俩其实本质上是一样的。就是埃及。httphttp.handle。是一样的啊,咱看一下啊,咱先。咱先试一下程序吧。看一下程序名叫什么。斜杠设计一技术方法一咱去打个斜杠。嗯。啊,跟目录。就是方法一。然后有个叫endpoint。
34:01
方法。是吧,没问题吧。那么我们去改造一下。啊。咱点handle handle去给他附加一个。这样行吗?他说我的一不是不是什么。常要一个handleno handleno。咱再咱再进去看一下啊,它是怎么写的啊。
35:07
看一下他是怎么写的。他留个憨豆。他这里是给他。做了一个转换吗?我们来试一下啊。一。诶诶,这样是不是可以。咱给抄过来啊。好,那么我们来看一下能不能得到我们的预期结果啊。
36:19
没有,是方法一。没问题啊,来刷新啊。是没问题的。好,这个例子呢,我们就讲完了,我们再去讲下面两种实现方式,好吧。好,实现方案三,实现方案三咱不看文档啊。
37:01
咱看代码实现方案三。实现方案三其实就是跟实现方案二里头我们看到的那个。两码你都是一样的啊,咱看下没有。源码,它是有定义一个默认的路由器,然后去给他添加这些handle的方法。这里呢,只是说我们去溜一个这么一个。哇。你有一个新的。你看这里有个默认的啊,之前都是用的默认的。人流那个新的。有这个新的之后呢,就和默其实一个用法嘛。啊,添加handle。那么我们来运行一下这个程序,咱也不多讲了啊,这个地方。
38:03
同样的东西反复讲就没有意思了啊。看到了。好,咱继续访问8080啊。访一个 resource8080的resource。好报404了,咱们看一下是什么一个情况。没错。就是应该报404,你看这里创建一个简单的handler to return404啊,这是HTB自带的一个啊,404的一个handle了。啊,这个看到呢,咱可以去给它替换掉啊,就比如说我们看一下。
39:03
他接收的一个。他接受一个string,接触一个handle。憨憨导,咱去做一个handle导啊,是吧。咱返回一个集体判道。你看。这个方法啊,就是我们。第二个例子里头的那个啊,咱从源码里面抄过来的那个啊。好,咱去给他剃一下。好。
40:00
我们再运行一下代码。Well this is是吧,No people handle,嗯,咱看一下。咱打印机是什么?This is no people handle。啊,说明它是。不对,在这里。ZC字这看一下啊,你确认一下。这是people啊,没错。看它就调用到了我们自己去写的这么一个处理程序啊。这里主要是讲就是说,嗯,咱HTTP也有自带的一些处理程序,嗯,咱自带的404。来看还有没有其他的啊。啊啊,咱看一下有没有其他的啊看一下。
41:08
这里有一个。好心。不一样。永远不这。午餐的这个大概就这一个啊。然后大家自己用的时候,平时用的时候可以去看一下啊。
42:00
好,我们再来试一下下面这一个。方法再看一眼。People写错了啊?好,可以正常访问,好,我们接下来进入下一个环节啊,下一个例子啊,下一个实现方案。下一个实现方案,下一个实现方案,下一个实现方案其实就是一个啊,多路多路复用的一个路由的一个实现方案啊。这个地方不一样的就是说它这里既包含了handle,又包含了handle fun。Function。咱去运行一下,咱也不多讲了,都讲过了。
43:31
一个根目录,一个API。啊,咱有成功的访问到这种。这个路由。嗯。咱API。铁站成功成交了啊。
44:05
啊,这个地方主要体现的就是说咱用handle也行,用handle function也行啊。这个地方就看自己的一个呃想法和呃具体的一个业务场景了。那么呢,HTTP发server的四种实现方案呢?我们都有去走了一遍。那么接下来我们做什么呢?我们就更进一步去实现这种get传插呢,POS传插呢啊,以及以po,以HTTP多路复用的方式去实现一个POS传传,然后去实现一个拦截器,这可能是我们在开发当中一定会要做的这么一个方向。啊,而不是仅仅是说去写几个例子,写几个例子,那请问这几个例子啊,在实际应用当中,其实是不会这么去写的啊。
45:06
好,我们去。看一下啊。我们直接看代码。好到我们第二部分。我们去实现一个。Get传菜。让咱看一下啊。可买函数,然后给他指定一个跟目录,指定一个叫handle的一个handle handle function。然后去建行8080啊,然后。然后这个hello,这个汉呢,去接收了。从一个请求的URL路径上去取它的query string啊,然后去get它的一个值,咱来请求一下。
46:23
他传的什么?ID name age?然后给它放到这么一个集合里头,通过Jason的一个序列化啊,这个打印出来。Idmh,咱来访问一下。ID等于十。莱姆本爱丽丝。
47:00
嗯。20岁。先请求一下。好,咱的结果成功打印出来了,是一个阶层格式的。这个地方大家注意一下,就是。购员的字典是无序的。它并不像其他有些语言,比如说PHP啊。嗯。他的那个字典是有序的,你比如说我ID先放去放进去啊,那它出来的一定是ID在前面。那这里不是的,你看你ID放进去了,是第一个放进去的,Name是第二个放进去的H第三个放进去的。它的顺序是不一样的啊。哎呀,我再重新运行一下,看他会不会改变啊。
48:05
这个据说还是嗯,购园官方特地这么做的。就是为了纠正。大家对。嗯,对构语言这么一个,呃对对集合这么一个有序做一个,呃,这个依赖的一个,呃解决方案吧。就防止大家去依赖集合的一个顺序,嗯,依赖集合的一个顺序,咱数据数组是有序的啊,这个是毋庸置疑的,但是集合啊,集合它是无序的。好,咱的一个get的一个请求做完了。好,咱再去实现一下post的post,看一下post啊。
49:00
同样的逻辑,但是我们这个方法改成了post啊,这个地方改成post post。好,咱这里需要把这个request先去pass pass一下啊。那我们需要什么呢?我们需要去启动一个post ma。那咱在网页上是不方便去做一个,嗯。POS的请求了。咋还加一个请求?咱先把它运行起来啊。
50:28
八零。咱用先用get去请求一下,咱看能不能去,嗯。获取到这么一个值啊。
51:10
Get也是可以。获取到的。大家知道问题出在哪里了吗?Get也能获取到。问题出在这个pass,咱去看一下pass的一个注释啊。
52:07
第二条语义的第二,嗯,这个。要pass的啊这个注释。通过pass去填充request.form和request post form,所以相当于是。他把URL上的参数去填充到了这个。嗯,request.form里头,所以我们的request.from value啊,就可以能够取到这么一个值。好。我们接下来做一。改为破子尖叫改为破子尖叫。好,这样能够取到,所以就没啥问题,但是如果反过来啊,我们的get的请求啊,Get的请求我们用POS去请求,它能不能获取到值呢?咱看一下啊,这个地方是以request的URl.query去取的值,所以这个地方理论上是获取不到的。
53:12
咱不信可以试一下,咱做一下实操啊。真能获取到,是因为我们的URL上是有值的啊。好,你看咱把URL上的值去掉,它就是获取不到的。那么我们的一个get和post啊,咱就讲完了,那么咱讲第三个。第三个是什么呢?是。一个多路复用的方式去实现一个破损传单啊,其实就是说咱的路由实现方式是不一样的。
54:04
咱看一下路由时间方式。去声明了这么一个路由啊,路由去指定两个方式。啊,咱直接运行。First。那么。好,刚first first打印的啥刚first。啊,First是打印了一个文本内容啊,说我们this is first。
55:00
Content。我们请教second这个方法。请求,Second second second。好,Second出来了,结果呢?没有值,问题出在哪?问题出在我们没有传值啊,咱看一下咱没有传值。ID。100。LA。爱丽丝。Age。18。没有我们的一个结果就出来了啊。没问题。
56:01
行,那我们相当于是我们的一个,呃,Web server的一个应用,我们相当于是更近了一步。其实它的主要应用还是在于嗯。路由这一块。Web serve的一个语法,其实就这样啊,这个路由这一块啊,这咱还有一个拦截器啊,拦截器没有说拦截器是什么东西呢。咱可能在呃,平时的一个业务开发当中,可能会需要有用到这么一个东西。为什么叫拦截器呢?其实就是说他要在handle之前去执行做一些。同样的操作。比如说我们平时业务开发当中的一个健全。或者说是啊。做一些同样的处理。比如说加解密之类的啊。
57:01
所以就有拦截器这么一说,拦截器无非就是说我在你之前处理,处理完了之后我再返回,再来处理你自己。咱看下啊。咱的serve还是同样的实现,只是说我们在handle了前面去加了一个拦截器,这个拦截器呢,它其实也是接触一个handle。他的返回单同样也是看到了。就这么一个逻辑。好,咱来执行一下。看他有没有起到一个拦截的作用。
58:20
好,我们来请求一下。外部。啊,没有输出我们看一眼啊。但是我们是有打印的。好,你看我们的拦截器是先执行的啊,先执行了拦截器的输出。然后再去执行的一个web的输出。
59:00
好,我们访问一下另外一个啊,问另外一个。没有先看到没有先执行的一个拦截器,然后去执行的一个my handle啊,所以拦截器这块是没问题的啊。好,我们的第二部分基本上就讲完了。嗯,我也不知道同学们有没有说,呃,经过第二部分实现了这个更进一步这么一个目的啊,就是。咱第二部分讲了一个get,讲了一个post,讲了一个多路复用的路由的一个post,以及一个呃,拦截器的实现。这只是简单的实现。那么我们接下来讲我们的第三部分。因为我们。
60:04
更进一步之后呢,我们还想再进一步,那再进一步是啥呢?就说一个API这一块。我们去呃,大概的讲讲,以及结合我们的一个呃。Web server去做一些实践和实践。首先我们要讲的一个话题是什么呢?首先什么是API?这个。据我的了解啊,API呢,它并不是说呃。类似于我们的,嗯,Web框架呀,比如说B购啊J。嗯。之类的一些框架,它不是的,它其实什么,它是跟。跟HTTP的协议差不多的一个东西,是一个概念。
61:00
或者说是一套规范,大家按这个规范走。那你就是API,如果你不按这个规范走,那你就不是API。它就就是一个规范,咱去看,咱看一下咱的一个文档描述。好,Rest API的全称啊,比较复杂,中文意思就是。表述的一个是。性状态转移。啊,首次出现,首次出现这些,就大家回头自己去百度看一看啊,咱去看。下面的一个,呃。情况。它的目标啊,目标是要得到一个功能性啊,功能强,性能好,适宜通讯的一个架构。然后rest指指的是一组架构约束条件和原则,看到没有,它是一组架构的约束条的条件和原则,就我们开发而言啊,这个东西就叫规范,我们按这个规范走。
62:07
那他就是热师傅架构,不按这个规范走,那它就不是热师傅架构。是吧,这个是刚才和我描述的,其实嗯,没有出入的啊。那么我们要怎么去理解?我们接着往下看,它其实是围绕着一个资源展开的一个讨论。资源。从各个方面去对资源进行一个描述。资源的定义啊,获取啊,表述啊,关联啊,状态的变迁啊。然后下面几个点呢,是一个资源与URL统一,资源接口,资源的表述,资源的链接状态的转移。咱接着往下看啊,看的有点迷糊啊。资源与URL。
63:00
简单的说,他的。概念就是一个URL,它就是一个资源。然后它指定的资源,比如说资源可以是实体啊,手机号啊,人的信息啊,多个用户的什么GP,嗯。GPS套餐啊是吧,这些其实都是资源。要让一个资源可以被识别到啊,需要有一个唯一标识。所以在web中,这个唯一标识就被定义成UR。所以为什么说URL?资源与URL。这的一个定义就是说我一个URL,它就是一个资源。你看这是下面他举的一些例子啊,就是说这些。这些URL是一些比较。
64:01
可读性比较好。比较规范的。你玩我的资源ID。好,统一资源接口,什么叫统一资源接口呢?这个地方就跟我们平时的一个开发就息息相关了啊。统一资源接口。比如说。它的一个规则是什么呢?嗯。比如说我要获取一个用户信息。那么我们去。如果是非。Free restful的一个定义的话,我们会做什么?我们会把这个,呃,Action可能会定义成一个动词,可能是get user,那些get user它有一个明显的。明显的一个。动作在里头是get,那么我们要删除这个用户的时候呢,我们会定义什么叫delete user,它也是一个,呃。
65:05
洞明。动宾结构。他的一个action非常明确的表述,我要获取一个用户,我要删除一个用户,我要修改一个用户。那这里的一个资源统一结口是什么呢?的一个要求,一个规范是什么呢?我的user没有动宾结构,User就是user。那么我要获取一个优者,我怎么办呢?我去通过。请求的method方式。去决定我这个资源是被获取还是被删除,还是被修改。比如说啊,咱看破子卖。咱postman里头有很多请求方法啊,Get post啊post。Delete啊,都有。
66:00
的一个规范就是我要get get user。那么我的一个。路径名,那我肯定就接user,那user行了啊,我获取ID唯一的user,那这就是get的user。那么我如果删除ID的user,那么我就delete,你看URL它是不会变的,所以这叫统一资源接口。你要post也是一样。然后POS来更新呢,或者是po来更新呢,啊,它这个URL它是不变的。这些统一资源接口。好,下面呢,就列出了对get delete put和post的一些典型用法,咱来挨个讲解一下。首先get。安全且密等。什么叫安全且密呢?安全意味着你误操作,没有关系。
67:06
不会对数据造成影响。密等,就是说你多次执行。它是同样的结果,没有问题。第二点是表示获取。变更时。变更时获取表示缓存。这一点呢?这一点目前我没有。Get到它的意思啊,大家回头自己去想想一个实际场景,什么叫变更时获取表示缓存。下面就是一些状态码啊,20015K啊,2045内容啊等等等等啊。好,那我们讲下一个那post post叫做。
68:04
地点不安全且不密。不安全,那就是你执行多了,它对数据造成影响的,所以是不安全。不密等,你多次执行,它就会多次插入或者多次更新,数据是会不断变化的,所以叫做不密等。使用服务端管理自动生产的实例号创建资源。这一点注意了啊。什么叫做使用服务端管理自动生产的实例号去创建资源呢?就比如说我去添加一个用户信息。我们的数据库表呢,怎么设计呢?我们的user ID呢?我们给它做一个自增的,由数据库产生的。那么我去新增这个用户信息的时候,我就应该用post。因为这个。
69:03
User的ID是由服务端产生的。那么换句话说,哪一种情况?不应该用。这种管理不应该用POS去创建资源呢?我想想怎么举个例子。比如说我们的商品录入。啊,我们就录一个商品。我的表怎么设计呢?我的表不设计,设计商品ID。他的实力号没有,他的实力号是什么呢。他的实力号就是我的条形码。那请问这个条形码从哪来的?那是不是商品上自带的一个条形码?它不是由服务端去管理的。那么此刻我去创建这个资源,我用什么呢?我应该用,我不应该用post,用什么我们接下来再看。
70:00
好吧。创建子资源。创建组资源呢,这个呃。大家自己理解,我目前不知道这个创建组资源是什么一个情况。下一个是部分更新资源,其实就是update。再下一个,如果没有被修改,则不过。则不更新资源。这种无非就是我的。数据没有被没有做任何修改,那我就不会对数据库去做操作。那这是一个常用的操作,比如说我在改之前,我先看一下我的。
71:03
啊,我传进来的和我库里有的是不是一样的啊,一样的那就没有必要改啊。接下来就是一些状态码啊,咱就不讲了。Put。不安全解密等。不安全。但密。呃,这个怎么理解呢?不安全,就是它会有数据往服务器去传。密等。这个大家实战实战去理解一下什么叫不安全且密等。
72:01
第二个,用客户端管理的实例号去创建一个资源。就我刚才说的,我post。是服务端管理的16号去创建一个资源,那put是客户端管理的16号去创建一个资源,相当于这个资源的一个唯一标识,是由客户端生成的。通过替换的方式更新资源。通过替换的方式更新资源。我的理解呢,就是说。不管我这个资源有没有被更新。啊,我都会去给他更新掉。甚至可能就是说,呃,我们去做一些修改的一些。操作修改等于什么呢?如果以替换的方式去更新的话,修改等于。
73:02
修改等于删了原来的,再加一条新的等于删除加新增,那就是我对这个啊,替换的方式去更新资源这么一个理解啊。好,他下一条是如果未被修改,则更新资源。就不管有没有更新,我都去更新资源。下面是一些状态吧,啊,咱也不说了。删除。啊,删除这个第一条好理解,不安全,但密等这个咱好理解啊。删除数据肯定是不安全的嘛,你操作就会对数据造成影响,所以是不安全的啊,但密密是你删了就一条你重复删。还是没问题。就所谓的密等啊等这个名词解释就是。
74:01
我多次操作不会对结果造成。不同影响。那我们回头看一下,这个put是不是也是这么一个概念,因为它是以替换的方式去更新资源。所以他多次操作它是不是也不会对结果造成影响?POS则不一样,POS我多次去新增。那可能导致的结果就是。我会产生多个ID。我同样的数据会产生多条,但是ID不一样,它的标识号不一样,但是boot,因为它的这个实例号。是由客户端管理的。只有同一个实力号进去。那它始终只会存在一条,所以幂等可能是这么一个解释。好,咱继续降。删除delete,它意味着删除一个资源。好,下面是一些,呃。做嘛。
75:00
接下来我们来看一下说常见的一些问题。Post和put用于创建资源时有什么区别?啊,这个我刚刚应该已经讲到了。无非就是说。一个是客户端来决定这个。标识号,就客户端管理和生成的一个标识号来决定这个资源。另一个是服务端去。决定和生成的。第二个需要注意的点。客户端不一定都支持HTTP方法。就我们通常的,嗯,Get post其实都是没有问题的,但是有一些比较老的浏览器。他可能就只支持盖那个铺子。他不知什么,然后PU啊put啊啊delete这么一些情况。
76:01
在实践中呢,呃。有些框架就通过支持隐藏参数啊,就是。可能在咱的head里头去加一个,呃,Method的这么一个。参数啊,可能加点前缀。来指定这么一个值。然后我们再。程序中处理的时候啊,去获取到这个值,然后去呃,走这么一个呃架构。第三点,统一接口是否意味着不能扩展带特殊语义的方法?啊,这也说了啊,就是统一结果并不阻止你扩展方法。就是你的优资源,你统一的接口正删改查都叫user。没有,也没有人阻止你啊,去加一个呃,非user的接口。
77:02
就比如说你要。加一个比较特殊的,比如叫叫什么呢。就是你非要加一个,比如说你非要加一个啊,我这编辑user啊,爱的user那也没问题。也没有人阻止你去做这种方式的扩展,只是说啊,我举的这个例子并不恰当,比如说我去增加一个ID的,这明显是呃,和我现在这个的一个架构是有一个呃冲突的啊,但它并不会产生实际的一些影响。比如说我们要加一个log user啊,就咱的user,咱user给他禁用了,咱啊咱可以加个log user,那没问题啊。因为我的里头我的HTTP的一个呃请求的method,它不包含这么一个呃请求,所以我去加一个log user,其实。
78:05
并不影响什么啊,它还是照样可以加。统一资源接口对UR的有什么指导意义?来看一下啊,统一资源接口要求使用标准的HT方法对资源进行操作。标准的htt方BHTTP方法对资源进行操作。所以URL应该只用来表示资源名,而不,而不应该包括资源的操作。这个地方什么?就是说我们既然统一了资源接口,而且通过标准的标的HTTP方法对资源进行操作,意味着我们对资源的操作。做什么操作已经。
79:01
被定义了。比如说我们get,那直接posts,直接用ittp的get must。啊,Post啊,Put delete,那你的资源的定义就仅仅只是资源了,它不不包含任何操作了,你看啊,咱他举的这几个例子啊,Get user,那get user,那这是不对的,我为什么get user呢?因为我的get已经有了,我应该就是get的方法啊USER1。Boss的也是。Post。But,同样也是。而不是说,而不要去包含这个动词结构了啊。好,下面的一些问题啊,直接忽视缓存可取吗?这个东西其实。你看啊,说了也不会去忽视这么一个缓存。咱只是说按各个动词原本的意图来使用它们。
80:02
我们去禁止缓存,照样是可以在响应图里面去增加,嗯,开始CTRL的。而且我们是可以去按不同的。处理函数啊,处理函数去。修改这个,嗯,缓存缓存控制这一块啊。就你不用担心,说我统一资源之后,嗯,我去给这个,呃。No catch会造成我的增删改查。都不使用catch了,不会的。我们可以单独的在每一个handle里头去设置它的no。再一个是响应代码的处理。啊,这个是我刚才没有讲到的一块儿。就是说我们用HTTP。
81:00
我们用rest for API,那么我们就一定需要啊,就一定要按他的一个规范,就是说。修改。请求的一个状态嘛。咱看一下。比如说delete。200是 ok200是OK,那就是说嗯,请求成功了。他这个200,它不是一个返回,返回数据里头的一个。错误码啊,它是一个响应码,是HTTP的响应码。五百五百就是服务器内部错误。就我们,嗯,通常去做程序开发的时候啊,咱500就是程序内部错误。咱看下POS卖啊。他的码不是在这个,不是在这个响应里头啊,是这个啊HTTP状态码看到没有。
82:07
他的建议是API的规范是我们是是需要去指定这个吗。好,那么我们对restful API的一个描述啊。一个讲解就完成了。那么接下来我们要做什么呢?我们是需要去。做一些实践。首先我们要实践。那么我们就要求我们的一个。我们就要求我们的一个web server的这个路由啊,路由至少是支持get post delete这些方法的,那咱就直接看例子。
83:03
这里呢,我们是引用的。第三方的一个http root。就他对root去做了一些封装。封装之后呢,我们的root就可以去是吧,去指定get post delete put这么些方法了。咱去看一下他的一个文档。这是他在github的一个源码啊,其实内容不多。咱看一下一个pass,一个root,一个tree。就这么几个。
84:02
大家有空呢,去看一下他这个源码,其实。这源码也不多啊,跟咱们平时看到的源码几百行啊,上千行啊,或者是几几百个文件啊,上千个文件,这还是呃量级不是一个量级啊,这种源码你去看的时候应该不会有那么大的抵触心理。那么我们来运行一下,运行一下我们。使用这个框架的啊,使用这个htp root这么一个东西的一个效果啊。在线运行下。狗。
85:01
好,我们来请求。咱先做一个。好,咱们看一下get返回的什么啊,Get是index这个handle。看到function,他直接return一个外。那么咱测试点什么呢?咱去给他这个get做成一个post啊,它为什么它会帮must not alone。没授权就是说。他不允许你这种没没有指定啊,就是没有被定义的这种POS的。方法去调用,比如说啊,我们在这里加一个什么呢。Route post。
86:08
如果是这样,那肯定没问题了,刚才是啥呢?刚才你看我们除了一个get跟目录。其他的都是没有这么一个,呃。方法的。所以我们这里加一个POS啊,那它肯定就没有问题了。咱看一下。你看POS可以使了。下面我们来试一下其他的。
87:04
咱来试下get Hollywood name。啊,Hello I'爱丽丝。好。啊,用作用做的了。咱来看一下,你看hello,爱丽丝。咱再来试一下其他的。I Du ID,咱来一个101。你看。You are get user101。哦,咱来挨悠着。
88:07
At their post。没有,还有走百01。那么现在有个问题我问大家,我们这里就是API吗?其实不是的。如果我们这里要做成API呢,首先要怎么着呢?我们来改造一下啊,看什么叫API。我们就以用户正常改查来说啊,咱这些先。嗯。都给他住了。我们get啊,首先我们定义一个资源,资源是什么?资源是user。
89:07
我们的资源都是user。Boost。Put,我们没有put应该。因为user。U的这个唯一标识,它一定是后台管理的。也是后台生成的,所以它不会有put这么一个函数,会有put这么一个method。但是我们有post啊。还有有有有。You delete。
90:06
还有吗?我们增删改查。这就我们的正常改查,然后我们给他做,嗯。加加参数UID。Post。I。How delete you?Get get也可以get u ID啊。他的某个用户。然后get,我们用index action。Post post,我没有爱。好。编辑。
91:03
这里的编辑呢?如果我们文档啊。API的一个描述啊,咱的一个。编辑、编辑、编辑。部分更新资源。他这个应该是。要用post而不是put啊。所以这个地方的编辑,编辑可能是需要有一个。我们需要去改造我们的user。
92:01
改动的user。怎么说呢?如果传入了UUID,那么我们应该去执行。Modify user如果没有传入UID,我们应该去执行ID user,就大概就这么一个情况。咱看一下啊。应该叫做。再来个方式。么?Z。一。
93:15
D等于PX点。By name,嗯,UID。If。ID不等于空字符串。那我们去执行什么呢?我们去执行。Modify user w r。是吧?Else,我们应该去执行I user。
94:02
2PS。嗯,我们应该用这个。没有,其实我们的正删改查就这三个方法啊,Get。咱同学的。同样的资源吧。资源名资源都叫user啊,盖的user啊,Poose的user POS user是两种情况,你传染UID,我们可能是需要去做一些。更改。啊,没有传UID,那么我们可能就是说去做一些新增。删除啊,删除我们同样是。那么这就是最简单的一个。API的一个实现。
95:03
好,我们来。调用一下。首先我们资源多,叫柚子。No。好,我们没有重新运行这个。服。看一下行不行。他说我修改了这个user。
96:01
是的,没错,因为我是调到的。而且我还传了。Uz ID,那么如果不传uz ID。不转UID,他会说我是。我放的。我们给他传零。还有修改了UI为零啊。咱这个地方做一下调整。我添加了一个UID啊,添加了一个user。
97:01
嗯,Name name,再看name,它name是取的哪个值啊。Have you all。嗯呢。Mobile form name form,它是form表单传进去的啊,Post post一个。那么。爱丽丝。哎,我添加了一个名字叫做爱丽丝的。就是。ADD。还有人。好,那么我们来更新,好,我们就101。那么我们给它叫做。Lucy。嗯。你看我修改了101的是吧,一个post即是实现了啊,新增又实现了。
98:06
啊,更新。好,我们来试一下,Get get get,我们get get。你看我们直接就调到get的一个index方法了。和的。好,说滴滴的有着。这就是一个最简单的API。首先我们的资源都是一定的是吧。资源名称,然后我们没有动宾结构。我们是通过。HTTP的这个GA的方式去做的处理。这就是一个API。
99:02
但还有一点我们要注意啊。啊,比如说。比如说我们添加失败了。添加失败了,我们去给他付一个p state啊,咱去给他付一个。500啊,服务器内不出,嗯,看一下。看一下能不能。
100:02
行。看到没有?这一个就是我们的一个状态嘛。就我操作失败了,那我就得去改变这个状态嘛。我操作成功了。那么我就得返还200。所以到这里呢,我们就是说整个rest API的一些重点我们都说到了是吧。它是一个规范。要统一资源名,然后。呃,以这种HTTP状态的方式去返回这个呃状态码啊。就是它的一个业务操作结果是跟HTP的一个状态码是保持一致的。第三个我们是以method的方式去做的一些操作啊。
101:05
所以。这就是一个最简单的一个呃rest API啊,大家可以去参考和借鉴。好,那么到这里呢,我们今天的课程呢,就接近尾声了啊,我们啊对。啊,我们对我们的web serve做了一些介绍,基本的语法递进的代码演讲啊,API啊,咱这些。都讲到了。最后呢?本章课,呃,本节课程呢的一些课件资料,主要就是一些文档。文档呢,就是我一个课件PPT一个是我的一个,呃。课件代码。
102:00
另外可能就是说有一些参考文档在那个。啊,PPT上PPT上都有描述啊,大概就是课件资料就这么一些。啊,今天的课程呢,就先到这里了啊,嗯,谢谢大家。
我来说两句