基于Go语言构建RESTful API服务

目录
  • 什么是 RESTful API
  • 一个简单的 RESTful API
  • RESTful JSON API
  • Gin 框架
    • 引入 Gin 框架
    • 使用 Gin 框架
    • 新增一个用户
    • 获取特定的用户
  • 总结

在实际开发项目中,你编写的服务可以被其他服务使用,这样就组成了微服务的架构;也可以被前端调用,这样就可以前后端分离。那么,本文主要介绍什么是 RESTful API,以及 Go 语言是如何玩转 RESTful API 的。

什么是 RESTful API

RESTful API 是一套规范,它可以规范我们如何对服务器上的资源进行操作。在了解 RESTful API 之前,我先为你介绍下 HTTP Method,因为 RESTful API 和它是密不可分的。

说起 HTTP Method,最常见的就是POST和GET,其实最早在 HTTP 0.9 版本中,只有一个GET方法,该方法是一个幂等方法,用于获取服务器上的资源,也就是我们在浏览器中直接输入网址回车请求的方法。

在 HTTP 1.0 版本中又增加了HEAD和POST方法,其中常用的是 POST 方法,一般用于给服务端提交一个资源,导致服务器的资源发生变化。

随着网络越来越复杂,发现这两个方法是不够用的,就继续新增了方法。所以在 HTTP1.1 版本的时候,一口气增加到了 9 个,新增的方法有 HEAD、OPTIONS、PUT、DELETE、TRACE、PATCH 和 CONNECT。下面我为你一一介绍它们的作用。

  • GET 方法可请求一个指定资源的表示形式,使用 GET 的请求应该只被用于获取数据。
  • HEAD 方法用于请求一个与 GET 请求的响应相同的响应,但没有响应体。
  • POST 方法用于将实体提交到指定的资源,通常导致服务器上的状态变化或副作用。
  • PUT 方法用于请求有效载荷替换目标资源的所有当前表示。
  • DELETE 方法用于删除指定的资源。
  • CONNECT 方法用于建立一个到由目标资源标识的服务器的隧道。
  • OPTIONS 方法用于描述目标资源的通信选项。
  • TRACE 方法用于沿着到目标资源的路径执行一个消息环回测试。
  • PATCH 方法用于对资源应用部分修改。

从以上每个方法的介绍可以看到,HTTP 规范针对每个方法都给出了明确的定义,所以我们使用的时候也要尽可能地遵循这些定义,这样我们在开发中才可以更好地协作。

理解了这些 HTTP 方法,就可以更好地理解 RESTful API 规范了,因为 RESTful API 规范就是基于这些 HTTP 方法规范我们对服务器资源的操作,同时规范了 URL 的样式和 HTTP Status Code。

在 RESTful API 中,使用的主要是以下五种 HTTP 方法:

  • GET,表示读取服务器上的资源;
  • POST,表示在服务器上创建资源;
  • PUT,表示更新或者替换服务器上的资源;
  • DELETE,表示删除服务器上的资源;
  • PATCH,表示更新 / 修改资源的一部分。

以上 HTTP 方法在 RESTful API 规范中是一个操作,操作的就是服务器的资源,服务器的资源通过特定的 URL 表示。

现在我们通过一些示例让你更好地理解 RESTful API,如下所示:

HTTP GET http://localhost:1000/users

HTTP GET http://localhost:1000/user/123

以上是两个 GET 方法的示例:

  • 第一个表示获取所有用户的信息
  • 第二个表示获取 ID 为 123 用户的信息

下面再看一个 POST 方法的示例,如下所示:

HTTP POST http://localhost:1000/user

这个示例表示创建一个用户,通过 POST 方法给服务器提供创建这个用户所需的全部信息。

现在你已经知道了如何创建一个用户,那么如果要更新某个特定的用户怎么做呢?其实也非常简单,示例代码如下所示:

HTTP PUT http://localhost:1000/user/123

这表示要更新 / 替换 ID 为 123 的这个用户,在更新的时候,会通过 PUT 方法提供更新这个用户需要的全部用户信息。这里 PUT 方法和 POST 方法不太一样的是,从 URL 上看,PUT 方法操作的是单个资源,比如这里 ID 为 123 的用户。

看到这里,相信你已经知道了如何删除一个用户,示例代码如下所示:

HTTP DELETE http://localhost:1000/user/123

DELETE 方法的使用和 PUT 方法一样,也是操作单个资源,这里是删除 ID 为 123 的这个用户。

一个简单的 RESTful API

相信你已经非常了解什么是 RESTful API 了,现在开始,我会带你通过一个使用 Golang 实现 RESTful API 风格的示例,加深 RESTful API 的理解。

Go 语言的一个很大的优势,就是可以很容易地开发出网络后台服务,而且性能快、效率高。在开发后端 HTTP 网络应用服务的时候,我们需要处理很多 HTTP 的请求访问,比如常见的RESTful API 服务,就要处理很多 HTTP 请求,然后把处理的信息返回给使用者。对于这类需求,Golang 提供了内置的 net/http 包帮我们处理这些 HTTP 请求,让我们可以比较方便地开发一个 HTTP 服务。

下面我们来看一个简单的 HTTP 服务的 Go 语言实现,代码如下所示:

func main() {

   http.HandleFunc("/users",handleUsers)

   http.ListenAndServe(":1000", nil)

}

func handleUsers(w http.ResponseWriter, r *http.Request){

   fmt.Fprintln(w,"ID:1,Name:张三")

   fmt.Fprintln(w,"ID:2,Name:李四")

   fmt.Fprintln(w,"ID:3,Name:王五")

}

这个示例运行后,你在浏览器中输入http://localhost:1000/users, 就可以看到如下内容信息:

ID:1,Name:张三

ID:2,Name:李四

ID:3,Name:王五

也就是获取所有的用户信息,但是这并不是一个 RESTful API,因为使用者不仅可以通过 HTTP GET 方法获得所有的用户信息,还可以通过 POST、DELETE、PUT 等 HTTP 方法获得所有的用户信息,这显然不符合 RESTful API 的规范。

现在我对以上示例进行修改,使它符合 RESTful API 的规范,修改后的示例代码如下所示:

func handleUsers(w http.ResponseWriter, r *http.Request){

   switch r.Method {

   case "GET":

      w.WriteHeader(http.StatusOK)

      fmt.Fprintln(w,"ID:1,Name:张三")

      fmt.Fprintln(w,"ID:2,Name:李四")

      fmt.Fprintln(w,"ID:3,Name:王五")

   default:

      w.WriteHeader(http.StatusNotFound)

      fmt.Fprintln(w,"not found")
   }
}

这里我只修改了 handleUsers 函数,在该函数中增加了只在使用 GET 方法时,才获得所有用户的信息,其他情况返回 not found。

现在再运行这个示例,会发现只能通过 HTTP GET 方法进行访问了,使用其他方法会提示 not found。

RESTful JSON API

在项目中最常见的是使用 JSON 格式传输信息,也就是我们提供的 RESTful API 要返回 JSON 内容给使用者。

同样用上面的示例,我把它改造成可以返回 JSON 内容的方式,示例代码如下所示:

//数据源,类似MySQL中的数据

var users = []User{

   {ID: 1,Name: "张三"},

   {ID: 2,Name: "李四"},

   {ID: 3,Name: "王五"},

}

func handleUsers(w http.ResponseWriter, r *http.Request){

   switch r.Method {

   case "GET":

      users,err:=json.Marshal(users)

      if err!=nil {

         w.WriteHeader(http.StatusInternalServerError)

         fmt.Fprint(w,"{\"message\": \""+err.Error()+"\"}")

      }else {

         w.WriteHeader(http.StatusOK)

         w.Write(users)

      }

   default:

      w.WriteHeader(http.StatusNotFound)

      fmt.Fprint(w,"{\"message\": \"not found\"}")

   }

}

//用户

type User struct {

   ID int

   Name string

}

从以上代码可以看到,这次的改造主要是新建了一个 User 结构体,并且使用 users 这个切片存储所有的用户,然后在 handleUsers 函数中把它转化为一个 JSON 数组返回。这样,就实现了基于 JSON 数据格式的 RESTful API。

运行这个示例,在浏览器中输入http://localhost:1000/users,可以看到如下信息:

[{"ID":1,"Name":"张三"},{"ID":2,"Name":"李四"},{"ID":3,"Name":"王五"}]

这已经是 JSON 格式的用户信息,包含了所有用户。

Gin 框架

虽然 Go 语言自带的 net/http 包,可以比较容易地创建 HTTP 服务,但是它也有很多不足:

  • 不能单独地对请求方法(POST、GET 等)注册特定的处理函数
  • 不支持 Path 变量参数
  • 不能自动对 Path 进行校准
  • 性能一般
  • 基于以上这些不足,出现了很多 Golang Web 框架,如 Mux,Gin、Fiber 等,今天我要为你介绍的就是这款使用最多的 Gin 框架。

引入 Gin 框架

Gin 框架是一个在 Github 上开源的 Web 框架,封装了很多 Web 开发需要的通用功能,并且性能也非常高,可以让我们很容易地写出 RESTful API。

Gin 框架其实是一个模块,也就是 Go Mod,所以采用 Go Mod 的方法引入即可。首先需要下载安装 Gin 框架,安装代码如下:

go get -u github.com/gin-gonic/gin

然后就可以在 Go 语言代码中导入使用了,导入代码如下:

import "github.com/gin-gonic/gin"

通过以上安装和导入这两个步骤,就可以在你的 Go 语言项目中使用 Gin 框架了。

使用 Gin 框架

现在,已经引入了 Gin 框架,下面我就是用 Gin 框架重写上面的示例,修改的代码如下所示:

func main() {

   r:=gin.Default()

   r.GET("/users", listUser)

   r.Run(":1000")

}

func listUser(c *gin.Context)  {

   c.JSON(200,users)

}

相比 net/http 包,Gin 框架的代码非常简单,通过它的 GET 方法就可以创建一个只处理 HTTP GET 方法的服务,而且输出 JSON 格式的数据也非常简单,使用 c.JSON 方法即可。

最后通过 Run 方法启动 HTTP 服务,监听在 1000 端口。现在运行这个 Gin 示例,在浏览器中输入http://localhost:1000/users,看到的信息和通过 net/http 包实现的效果是一样的。

新增一个用户

现在你已经可以使用 Gin 获取所有用户,还可以获取特定的用户,那么你也应该知道如何新增一个用户了,现在我通过 Gin 实现如何新增一个用户,看和你想的方案是否相似。

根据 RESTful API 规范,实现新增使用的是 POST 方法,并且 URL 的格式为http://localhost:1000/users,向这个 URL 发送数据,就可以新增一个用户,然后返回创建的用户信息。

现在我使用 Gin 框架实现新增一个用户,示例代码如下:

func main() {

   //省略没有改动的代码

   r.POST("/users", createUser)

}

func createUser(c *gin.Context) {

   name := c.DefaultPostForm("name", "")

   if name != "" {

      u := User{ID: len(users) + 1, Name: name}

      users = append(users, u)

      c.JSON(http.StatusCreated,u)

   } else {

      c.JSON(http.StatusOK, gin.H{

         "message": "请输入用户名称",

      })

   }

}

以上新增用户的主要逻辑是获取客户端上传的 name 值,然后生成一个 User 用户,最后把它存储到 users 集合中,达到新增用户的目的。

在这个示例中,使用 POST 方法来新增用户,所以只能通过 POST 方法才能新增用户成功。

现在运行这个示例,然后通过如下命令发送一个新增用户的请求,查看结果:

➜ curl -X POST -d 'name=Ele' http://localhost:1000/users

{"ID":4,"Name":"Ele"}

可以看到新增用户成功,并且返回了新增的用户,还有分配的 ID。

获取特定的用户

现在你已经掌握了如何使用 Gin 框架创建一个简单的 RESTful API,并且可以返回所有的用户信息,那么如何获取特定用户的信息呢?

下面我通过 Gin 框架 Path 路径参数来实现获得特定用户的信息功能,示例代码如下:

func main() {

   //省略没有改动的代码

   r.GET("/users/:id", getUser)

}

func getUser(c *gin.Context) {

   id := c.Param("id")

   var user User

   found := false

   //类似于数据库的SQL查询

   for _, u := range users {

      if strings.EqualFold(id, strconv.Itoa(u.ID)) {

         user = u

         found = true

         break

      }

   }

   if found {

      c.JSON(200, user)

   } else {

      c.JSON(404, gin.H{

         "message": "用户不存在",

      })

   }

}

在 Gin 框架中,路径中使用冒号表示 Path 路径参数,比如示例中的 :id,然后在 getUser 函数中可以通过 c.Param("id") 获取需要查询用户的 ID 值。PS:Param 方法的参数要和 Path 路径参数中的一致,比如示例中都是 ID。

现在运行这个示例,通过浏览器访问http://localhost:1000/users/4,就可以获得 ID 为 4 的用户,输出信息如下所示:

{"ID":4,"Name":"Ele"}

可以看到,已经正确的获取到了 ID 为 4 的用户,他的名字叫Ele。

假如我们访问一个不存在的 ID,会得到什么结果呢?比如 99,示例如下所示:

curl http://localhost:1000/users/99

{"message":"用户不存在"}

从以上示例输出可以看到,返回了『用户不存在』的信息,和我们代码中处理的逻辑一样。

总结

Go 语言已经给我们提供了比较强大的 SDK,让我们可以很容易地开发网络服务的应用,而借助第三方的 Web 框架,可以让这件事情更容易、更高效。比如这篇文章介绍的 Gin 框架,就可以很容易让我们开发出 RESTful API。在我们做项目开发的时候,要善于借助已经有的轮子,让自己的开发更有效率,也更容易实现。

到此这篇关于基于Go语言构建RESTful API服务的文章就介绍到这了,更多相关Go语言构建RESTful API 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Django开发RESTful API实现增删改查(入门级)

    数据库中有user表如下: 新建一个Django项目: django-admin.py startproject myDjango<project_name> 目录介绍 myDjango/ ├── manage.py # 管理文件 └── myDjango # 项目目录 ├── __ init __.py ├── settings.py # 配置文件 ├── urls.py # 路由 --> URL和函数的对应关系 └── wsgi.py # runserver命令就使用wsgiref模

  • go 原生http web 服务跨域restful api的写法介绍

    错误写法 func main() { openHttpListen() } func openHttpListen() { http.HandleFunc("/", receiveClientRequest) fmt.Println("go server start running...") err := http.ListenAndServe(":9090", nil) if err != nil { log.Fatal("Liste

  • 详解Go语言RESTful JSON API创建

    RESTful API在Web项目开发中广泛使用,本文针对Go语言如何一步步实现RESTful JSON API进行讲解, 另外也会涉及到RESTful设计方面的话题. 也许我们之前有使用过各种各样的API, 当我们遇到设计很糟糕的API的时候,简直感觉崩溃至极.希望通过本文之后,能对设计良好的RESTful API有一个初步认识. JSON API是什么? JSON之前,很多网站都通过XML进行数据交换.如果在使用过XML之后,再接触JSON, 毫无疑问,你会觉得世界多么美好.这里不深入JSO

  • Django restful framework生成API文档过程详解

    自动生成api文档(不管是函数视图还是类视图都能显示) 1.安装rest_framework_swagger库 pip install django-rest-swagger 2.在项目下的 urls.py 中加入如下: from rest_framework_swagger.views import get_swagger_view schema_view = get_swagger_view(title='API文档') urlpatterns += [ path(r'docs/', sch

  • Django JWT Token RestfulAPI用户认证详解

    一般情况下我们Django默认的用户系统是满足不了我们的需求的,那么我们会对他做一定的扩展 创建用户项目 python manage.py startapp users 添加项目apps settings.py INSTALLED_APPS = [ ... 'users.apps.UsersConfig', ] 添加AUTH_USRE_MODEL 替换默认的user AUTH_USER_MODEL = 'users.UserProfile' 如果说想用全局认证需要在配置文件中添加 # 全局认证f

  • 详解Django rest_framework实现RESTful API

    一.什么是REST 面向资源是REST最明显的特征,资源是一种看待服务器的方式,将服务器看作是由很多离散的资源组成.每个资源是服务器上一个可命名的抽象概念.因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件.数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解. 与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词.一个资源可以由一个或多个URI来标识.URI既是资源的名称,也是资源在Web上的地址.对某个资

  • Python利用Django如何写restful api接口详解

    前言 用Python如何写一个接口呢,首先得要有数据,可以用我们在网站上爬的数据,在上一篇文章中写了如何用Python爬虫,有兴趣的可以看看://www.jb51.net/article/141661.htm 大量的数据保存到数据库比较方便.我用的pymsql,pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前在python3.x中,PyMySQL取代了MySQLdb. 1.连接数据库 # 连接数据库,需指定charset否则可能会报错 db = pym

  • 基于Go语言构建RESTful API服务

    目录 什么是 RESTful API 一个简单的 RESTful API RESTful JSON API Gin 框架 引入 Gin 框架 使用 Gin 框架 新增一个用户 获取特定的用户 总结 在实际开发项目中,你编写的服务可以被其他服务使用,这样就组成了微服务的架构:也可以被前端调用,这样就可以前后端分离.那么,本文主要介绍什么是 RESTful API,以及 Go 语言是如何玩转 RESTful API 的. 什么是 RESTful API RESTful API 是一套规范,它可以规范

  • Go快速开发一个RESTful API服务

    目录 何时使用单体 RESTful 服务 商城单体 RESTful 服务 单体服务实现 Mall API 定义 账号模块 API 定义 订单模块 API 定义 商品模块 API 定义 生成单体服务 实现业务逻辑 总结 何时使用单体 RESTful 服务 对于很多初创公司来说,业务的早期我们更应该关注于业务价值的交付,而单体服务具有架构简单,部署简单,开发成本低等优点,可以帮助我们快速实现产品需求.我们在使用单体服务快速交付业务价值的同时,也需要为业务的发展预留可能性,所以我们一般会在单体服务中清

  • 如何集成swagger2构建Restful API

    这篇文章主要介绍了如何集成swagger2构建Restful API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在pom.xml中进行版本管理 <swagger.version>2.8.0</swagger.version> 给taosir-api的pom.xml中添加依赖配置 <!-- swagger start --> <dependency> <groupId>io.springfox

  • 使用ASP.NET Web API构建Restful API

    目录 一.前言 二.获取所有数据 三.获取详情 四.新增数据 五.修改数据 六.删除数据 七.特性路由 (1) 基本路由映射 (2) 路由映射参数 (3) 多重特性路由 (4) 缺省参数路由 (5) 参数约束路由 (6) 通配符(*)路由变量 (7) 路由映射复杂参数 (8) 路由前缀 一.前言 RESTful API 是基于HTTP协议产生的一种相对简单的API设计方案: RESTful 的核心是 everything is a “resource”,所有的HTTP action,都应该是相应

  • Spring MVC集成springfox-swagger2构建restful API的方法详解

    前言 在集成springfox-swagger2之前,我也尝试着集成了swagger-springmvc,方式差不多,但是swagger-springmvc相对麻烦一点,因为要把它的静态文件copy到自己的项目中.所以还是用新版本的. 至于两者有什么不同,为什么进行版本变更请参见官方说明文档 方法如下 这里先写下需要的pom.xml配置(我引用的2.4.0,相对稳定) <dependency> <groupId>io.springfox</groupId> <ar

  • Spring Boot集成springfox-swagger2构建restful API的方法教程

    前言 之前跟大家分享了Spring MVC集成springfox-swagger2构建restful API,简单写了如何在springmvc中集成swagger2.这边记录下在springboot中如何集成swagger2.其实使用基本相同. 方法如下: 首先还是引用相关jar包.我使用的maven,在pom.xml中引用相关依赖(原来我使用的是2.2.0的,现在使用2.4.0的): <dependency> <groupId>io.springfox</groupId&g

  • 详解Spring Boot实战之Restful API的构建

    上一篇文章讲解了通过Spring boot与JdbcTemplate.JPA和MyBatis的集成,实现对数据库的访问.今天主要给大家分享一下如何通过Spring boot向前端返回数据. 在现在的开发流程中,为了最大程度实现前后端的分离,通常后端接口只提供数据接口,由前端通过Ajax请求从后端获取数据并进行渲染再展示给用户.我们用的最多的方式就是后端会返回给前端一个JSON字符串,前端解析JSON字符串生成JavaScript的对象,然后再做处理.本文就来演示一下Spring boot如何实现

  • 浅析Node在构建超媒体API中的作用

    无论是超媒体还是超文本,使用的传输协议都是HTTP,这意味着超媒体可以被所有的浏览器所接受.而描述超媒体的类型我们使用MIME.MIME即Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型,MIME是一个互联网标准,最早是应用于电子邮件系统的,后来其定义逐步应用到互联网领域.用MIME指定媒体的类型,那么客户端浏览器就能清楚地知道,该如何处理这种类型的媒体. Node.js是基于谷歌V8 JavaScript引擎构建的一种库,主要用于方便.快捷的

  • 用Node编写RESTful API接口的示例代码

    前言 本文介绍了如何用Node开发web程序,并通过一个todo list练习来介绍如何创建符合RESTful风格的API接口. 创建HTTP服务器 用Node创建HTTP服务器是非常方便的. 创建HTTP服务器要调用http.createServer()函数,它只有一个参数,是个回调函数,服务器每次收到HTTP请求后都会调用这个回调函数.这个回调会收到两个参数,请求和响应对象,通常简写为req和res: var http = require('http') var server = http.

  • 使用 Spring Boot 2.0 + WebFlux 实现 RESTful API功能

    概述 什么是 Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发框架. 要深入了解 Spring WebFlux, 首先要了知道 Reactive Stream . 另一种编程姿势, 和命令式编程相对的姿势. WebFlux 支持两种编程风(姿)格(势) 使用 @Controller 这种基于注解的姿势, 与Sring MVC的姿势相同 基于Java 8 Lambda的函数式编程风格 注意: 上面只是两种编程的姿势, 和"普通话

随机推荐