Go 语言 API 开发

1. 概述和要求

        REST 是 Representational State Transfer 的缩写。可以使用 REST 来公开 Web 应用程序中的信息,并允许其他应用程序访问该信息。REST 本质上是一种可用于让 Web 应用程序访问资源以及另一个系统上资源状态信息的架构。通过使用 RESTful API,可以与其他服务器和系统进行交互。

下面将介绍如何创建一些有助于处理远程进程的元素。

  • 请求:请求是 HTTP 请求。 API 内部的所有请求都是以 HTTP 请求的形式进行的。
  • 处理程序:处理程序是一个处理客户端传入请求的函数。每种类型的请求都应该有一个适当的处理程序进行处理,并向该请求提供响应。
  • 路由器:路由器是将一个 API 的端点映射到相应的处理程序的函数。

        我们的目标是创建一个完整的 RESTful API,该 API 使用 GET、POST、PUT 和 DELETE 这 4 种 HTTP 请求来创建、读取、更新和删除数据(完成数据的 CRUD 操作)。CRUD 操作对应的 HTTP 请求如下:

  • POST: 向数据集中添加新数据。
  • GET:检索现有数据
  • PUT: 更新现有数据
  • DELETE: 删除现有数据

2. 第一步:创建数据集和一个简单的 API

        第一步是规划基本元素并将其添加到程序中。要构建 API,需要使用以下包。

  • encoding/json: 这个包可以把从请求中接收到的 JSON 数据解析为 Go 数据,反之亦然。
  • log: log 包允许为 API 实现日志功能,例如记录请求中的错误。
  • net/http:这个包允许接收、解析和发送 HTTP 请求。

        创建一个新程序并添加所需的包,如下代码所示:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)
2.1 定义数据集

        下一步是定义将对其执行 CRUD 操作的数据集。对于这个简单的例子,我们希望从以下字段开始。

  • Number: 帐号编号
  • Balance: 当前帐户余额
  • Desc: 帐户类型

        这个数据集的定义将作为一个基本表示,但如果有必要,可以包括其他字段。可以将这些字段映射到 JSON 数据集中的相应字段。

type Account struct {
	Number  string  'json:"AccountNumber"'
	Balance string	'json:"Balance"'
	Desc    string	'json:"AccountDescription"'
}

        我们还将创建一个帐户数据集并将其存储在一个切片中。因为有多个不同的函数来访问此数据集,所以在 main 函数之外将它定义为全局变量。直接在结构体之后添加这个变量。

var Accounts []Account

        另一种选择是将 Accounts 数据集创建为局部变量,然后将其传递给每个函数。 

package main

import (
   "encoding/json"
   "fmt"
   "log"
   "net/http"
   "github.com/gorilla/mux"
   "io/ioutil"
)

// we create a type Account that will be used to represent a bank account
type Account struct {
   Number string `json:"AccountNumber"`
   Balance string `json:"Balance"`
   Desc string `json:"AccountDescription"`
}

// we use Accounts as a global variable because it is used by
// several functions in the code
var Accounts []Account

// implement the homePage
// use the ResponseWriter w to display some text when we visit the home page
func homePage(w http.ResponseWriter, r *http.Request){
   fmt.Fprintf(w, "Welcome to our bank!")
   // we can use a print command to log the request or we can log it to a file, etc.
   fmt.Println("Endpoint: /")
}

// handleRequests will process HTTP requests and redirect them to
// the appropriate Handle function
func handleRequests() {
   // create a router to handle our requests from the mux package.
   router := mux.NewRouter().StrictSlash(true)
   // access root page
   router.HandleFunc("/", homePage)
   // returnAllAccounts
   router.HandleFunc("/accounts", returnAllAccounts)
   // return requested account
   router.HandleFunc("/account/{number}", returnAccount)
   // create new account
   router.HandleFunc("/account", createAccount).Methods("POST")
   // delete requested account
   router.HandleFunc("/account/{number}", deleteAccount).Methods("DELETE")
   // define the localhost
   log.Fatal(http.ListenAndServe(":10000", router))
}

// return the dataset Accounts in a JSON format
func returnAllAccounts(w http.ResponseWriter, r *http.Request){
   // we use the Encode function to convert the Account slice into a json object
   json.NewEncoder(w).Encode(Accounts)
}

// return a single account
func returnAccount(w http.ResponseWriter, r *http.Request){
   vars := mux.Vars(r)
   key := vars["number"]
   for _, account := range Accounts {
      if account.Number == key {
         json.NewEncoder(w).Encode(account)
      }
   }
}

// create a new account
func createAccount(w http.ResponseWriter, r *http.Request) {
   reqBody, _ := ioutil.ReadAll(r.Body)
   var account Account
   json.Unmarshal(reqBody, &account)
   Accounts = append(Accounts, account)
   json.NewEncoder(w).Encode(account)
}

func deleteAccount(w http.ResponseWriter, r *http.Request) {
   // use mux to parse the path parameters
   vars := mux.Vars(r)
   // extract the account number of the account we wish to delete
   id := vars["number"]
   // we then need to loop through dataset
   for index, account := range Accounts {
      // if our id path parameter matches one of our
      // account numbers
      if account.Number == id {
         // updates our dataset to remove the account
         Accounts = append(Accounts[:index], Accounts[index + 1:]...)
      }
   }
}

func main() {
   // initialize the dataset
   Accounts = []Account{
      Account{Number: "C45t34534", Balance: "24545.5", Desc: "Checking Account"},
      Account{Number: "S3r53455345", Balance: "444.4", Desc: "Savings Account"},
   }

   // execute handleRequests, which will kick off the API  
   // we can access the API using the the URL defined above
   handleRequests()
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mindfulness code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值