Day15 Gin's Router And RESTful API

What is API and HTTP?

API得全名叫做Application Programming Interface,也就是一个应用程序的街口,让第三方可以进行开发、应用在其他用途上的沟通管道。

但首先需要先介绍一下HTTP,HTTP全名Hypertext Transfer Protocol,在该Protocol有Client、Server两种人,举例来说,Client指的就是我、Server指的就是Google,我在点击Google首页时,我就是像Google的Server传送了这个请求,然後Google在回应所需资源给我。但为了要让Request与Response有统一个规范,才诞生出HTTP。

举例来说,我们搜寻了某个在Google下的网址会有以下步骤:

  • 我们在浏览器输入Google网址,并点击Enter,送出Request
  • Server收到Request,并检查该Request的合法性
  • Server依照该Request回应相对应的Response

Response会依照该Request的合法性给出相对应的状态码,状态码也能够大致分为以下种类:

  • 2XX: Success(成功)
  • 3XX: Redirect(重新定向)
  • 4XX: User Error(客户端错误)
  • 5XX: Server Error(服务器端错误)

此外,在HTTP中会有许多种不同method的请求行为,最常见的就是GET / POST / PUT /DELETE,
这些method也刚好会对应到资料库的基本操作CRUD行为(Create, Read, Update, Delete)

What is RESTful API ?

REST全名为Representational State Transfer( 表现层状态转移),他是一种设计风格,而RESTful则形容以此规范设计的API,称为RESTfuk API。

RESTful API主要由三种不同元件组成:

restful.png

  • Nouns名词: 定义Server资源位置的URL,就像每个人家中的地址一样。
  • Verbs动词: 对该资源所要采取的动作。
  • Content Types资源呈现方式: API资源可以以多种方式表现,最常用的JSON,较轻也较好处理。

一般的API,可能呈现方式会是这样:

新增资料POST /createData
获得资料GET /getData/1
删除资料DELETEe /deleteData/1

不同公司,不一样的工程师,设计的名称都会不一样,也没有统一的命名方式,造成在引用各家 API 时,都需要详读 API 文件,理解所有设计命名规则後,才可使用。

若是以RESTful API的风格开发的话:

新增资料POST    /data ,Method: POST
获得资料GET     /data ,Method: GET
删除资料DELETE  /data/1 ,Method: DELETE

就是用一个唯一的URL定位资源,将动作藏在HTTP的method里面。

所以使用RESTful风格设计的API,就会有以下几种优点以及限制:

  1. 有唯一的URL表示资源位置,并提供统一的API接口(Uniform Interface)
  2. 无状态(Stateless)

RESTful的状态即是HTTP的请求状态,在一般Web服务中,Server Side与Client Side交互的资讯会存在Server Side的Session(像是登入状态等),在Client Side再次发起请求时,Server Side会透过保存的Session去执行Request。而无状态的意思就是Client Side会自行保存状态,在对Server Side发出请求时,一并将其附给Server Side,Server Side并不会保存Client Side的状态。

举例来说,在用户登录系统时,Server 产生 token 纪录 user 已登录系统,然後把 token 还给 Client,在 Client 再次发送请求的时候,把 token 一起发给 Server,这样 Server 就知道这一个 Client 是已经处於登录的状态。

  1. 更高效利用快取来提高回应速度 (Cachable),在Server中被GET过的资源在没有变更的情况之下可以利用Cache暂存若干时间,减少request。在Client中,透过Client的cache纪录,若向Server要求的资源版本与Cache相同,则直接对本地Cache进行调用,无需再多做一次GET。
  2. 分层系统就够
  3. 客户端服务器分离
  4. 乾净且目标明确的使用HTTP Method

Routing in Gin

Using GET, POST, PUT, PATCH, DELETE and OPTIONS @ API Example

  • gin.Default():使用 gin router 预设的 middleware,包含 logger 和 recover (crash-free) 的 middleware
  • router.Run():预设是 :8080 ,可以用字串修改,例如 router.Run(":3000")
  • router.GET(): 前面的GET, POST表示方法,後面参数则是表示路径以及接收Request执行的行为

简单举例如下

func main() {
    // Creates a gin router with default middleware:
    // logger and recovery (crash-free) middleware
    router := gin.Default()

    router.GET("/someGet", getting)
    router.POST("/somePost", posting)
    router.PUT("/somePut", putting)
    router.DELETE("/someDelete", deleting)
    router.PATCH("/somePatch", patching)
    router.HEAD("/someHead", head)
    router.OPTIONS("/someOptions", options)

    // By default it serves on :8080 unless a PORT environment variable was defined.
    router.Run()
    // router.Run(":3000") for a hard coded port
}

Parameters in Path

取得网址中的 params:

  • 在路由设定中
    • 使用 :<filed> 可以定义动态路由(只能匹配到 / 以前)
    • 使用 <filed> 可以定义动态路由(可以匹配到 / 以後)
  • c.Param("<field>") 可以取得网址中的参数
  • c.Fullpath() 可以取得定义的路由参数
func main() {
    router := gin.Default()

    router.GET("/user", func(c *gin.Context) {
        c.String(200, "/user")
    })

    router.GET("/user/:name", func(c *gin.Context) {
        fmt.Println(c.FullPath())  // /user/:name/
        name := c.Param("name")
        c.String(http.StatusOK, "Hello %s", name)
    })

    router.GET("/user/:name/*action", func(c *gin.Context) {
        fmt.Println(c.FullPath())   // /user/:name/*action
        name := c.Param("name")
        action := c.Param("action")
        message := name + " is " + action
        c.String(http.StatusOK, message)
    })

    router.Run(":3000")
}
  • "/user/:name": 这并不会使其匹配到/user/ 或是
  • "/user/:name/*action": 这就会使其匹配到/user/flynn/ 或是 /user/flynn/send

Summary

这章节主要介绍RESTful API以及简单Gin Router的使用,在下个章节则会示范Gin的项目结构一般来说会长怎麽样,如何配合middleware来建立起简单乾净的routing structure。


<<:  Day 15 - Spring Boot 注册与登入

>>:  Day 16 | FPS灭火AR游戏开发Part1 - 水柱粒子系统制作

Day 8 规划用户的个资自主权

全球个资保护如雨後春笋般的出现,各国对於个资保护的意识更加积极主动,且也陆续参考GDPR进行个资隐私...

Day11 do-while

While 是前测式回圈,在执行陈述式前先测试条件式是否符合,反之,後测式後测式回圈是不管条件式有没...

如何让 IIS 底下的 PHP 显示错误内容 (500 Error)

今天在IIS上安装的PHP发生了错误,可是一直出现 500-内部服务器错误,这样会看不到正确的错误内...

渗透测试-枚举(Enumeration)

-渗透侧试方法 设计该问题的目的是指出存在多种渗透测试方法,渗透测试人员可能会不一致地使用这些术语...

Rust-流程控制-while

类似PHP的while回圈,计算其後的布林条件如果是值为true则执行大括号下面的语法,会重复条件的...