成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用Go實(shí)現(xiàn)一個(gè)帶緩存的REST API服務(wù)端

開(kāi)發(fā) 后端 網(wǎng)絡(luò)
本文我將使用Go語(yǔ)言來(lái)設(shè)計(jì)一個(gè)REST API的服務(wù)端, 這里的模擬場(chǎng)景是通過(guò)服務(wù)端來(lái)對(duì)外提供文章的增、刪、查服務(wù)。

1.REST API原理

REST(Representational State Transfer)是一種通過(guò)HTTP協(xié)議設(shè)計(jì)API的架構(gòu)風(fēng)格,用于構(gòu)建分布式系統(tǒng)中的網(wǎng)絡(luò)應(yīng)用程序。REST API(RESTful API)是基于這種設(shè)計(jì)風(fēng)格的應(yīng)用程序編程接口。其主要優(yōu)點(diǎn)是其極大的靈活性, 只要需要直接從服務(wù)器向Web應(yīng)用程序或站點(diǎn)的用戶(hù)提供數(shù)據(jù), 開(kāi)發(fā)人員直接使用REST API即可實(shí)現(xiàn)。

REST API 的設(shè)計(jì)目的是創(chuàng)建簡(jiǎn)單、可伸縮、可維護(hù)且具有良好可讀性的接口, 以促進(jìn)客戶(hù)端和服務(wù)器之間的有效通信, 通過(guò)使用HTTP協(xié)議和一組統(tǒng)一的設(shè)計(jì)原則, REST API在實(shí)現(xiàn)上具備一些特定的屬性:

  • 資源(Resources):在REST中, 數(shù)據(jù)或服務(wù)都被視為資源。每個(gè)資源都有一個(gè)唯一的標(biāo)識(shí)符, 用于在網(wǎng)絡(luò)上標(biāo)識(shí)和定位該資源。
  • 表現(xiàn)層(Representation):資源的狀態(tài)可以以不同的表現(xiàn)形式呈現(xiàn), 例如: JSON、XML或HTML。客戶(hù)端可以通過(guò)請(qǐng)求特定的表現(xiàn)形式來(lái)與服務(wù)器交互。
  • 狀態(tài)無(wú)關(guān)(Stateless):REST是狀態(tài)無(wú)關(guān)的, 這意味著每個(gè)請(qǐng)求從客戶(hù)端到服務(wù)器都包含了足夠的信息, 服務(wù)器不需要存儲(chǔ)客戶(hù)端的狀態(tài)。每個(gè)請(qǐng)求都應(yīng)該包含了執(zhí)行該請(qǐng)求所需的所有信息。
  • 統(tǒng)一接口(Uniform Interface):RESTful API的設(shè)計(jì)應(yīng)該遵循一致的接口原則, 使得不同的組件之間的通信變得簡(jiǎn)單統(tǒng)一。
  • 無(wú)狀態(tài)通信(Stateless Communication):每個(gè)請(qǐng)求從客戶(hù)端到服務(wù)器都應(yīng)該包含足夠的信息, 以便服務(wù)器能夠理解和處理請(qǐng)求,而無(wú)需依賴(lài)之前的請(qǐng)求。
  • 緩存(Cacheability):REST API支持緩存, 以提高性能和減輕服務(wù)器的負(fù)擔(dān)。服務(wù)器可以在響應(yīng)中指定數(shù)據(jù)的緩存策略,而客戶(hù)端可以使用緩存來(lái)避免重復(fù)請(qǐng)求相同的數(shù)據(jù)。
  • 使用標(biāo)準(zhǔn)方法(Standard Methods):REST使用標(biāo)準(zhǔn)的HTTP方法,如:GET、POST、PUT、DELETE來(lái)執(zhí)行不同的操作, 這些方法對(duì)應(yīng)于對(duì)資源的不同操作, 使得API的使用更加直觀和符合HTTP標(biāo)準(zhǔn)。

2.REST API服務(wù)端設(shè)計(jì)

下面我將使用Go語(yǔ)言來(lái)設(shè)計(jì)一個(gè)REST API的服務(wù)端, 這里的模擬場(chǎng)景是通過(guò)服務(wù)端來(lái)對(duì)外提供文章的增、刪、查服務(wù), 文章的查詢(xún)方式包括兩種: 1.查詢(xún)服務(wù)器所有文章內(nèi)容。2.根據(jù)文章ID查詢(xún)某篇文章的內(nèi)容。

文章的屬性包括三個(gè)字段: 文章ID、文章標(biāo)題、文章內(nèi)容, 這里可以用一個(gè)結(jié)構(gòu)體表示:

type Article struct {
  ID string `json:"id,omitempty"`
  Title string `json:"title,omitempty"`
  Content string `json:"content,omitempty"`
}

由于我們?cè)O(shè)計(jì)了四個(gè)功能接口, 將其轉(zhuǎn)換成接口代碼框架如下:

// 獲取所有文章接口
func GetArticles(w http.ResponseWriter, r *http.Request) {
     ...
}

// 獲取單篇文章接口
func GetArticle(w http.ResponseWriter, r *http.Request) {
     ...
}

// 創(chuàng)建文章接口
func CreateArticle(w http.ResponseWriter, r *http.Request) {
     ...
}

// 刪除文章接口
func DeleteArticle(w http.ResponseWriter, r *http.Request) {
     ...
}

3.功能代碼實(shí)現(xiàn)

首先來(lái)實(shí)現(xiàn)獲取所有文章的接口, 具體參考代碼如下:

// 獲取所有文章
func GetArticles(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")

  // 嘗試從緩存中獲取文章列表
  if cachedArticles, found := articleCache.Load("all"); found {
    json.NewEncoder(w).Encode(cachedArticles)
    return
  }

  // 從原始數(shù)據(jù)源獲取文章列表
  json.NewEncoder(w).Encode(Articles)

  // 將文章列表存入緩存
  articleCache.Store("all", Articles)
}

獲取所有文章首先是嘗試從緩存中獲取文章列表, 緩存cachedArticles這里實(shí)際是一個(gè)sync.Map類(lèi)型的變量, 支持并發(fā)安全, 如果找到的話, 直接序列化成JSON的格式返回。如果緩存中沒(méi)有找到, 則從原始數(shù)據(jù)源中獲取文章列表(實(shí)際應(yīng)用中應(yīng)該是從數(shù)據(jù)庫(kù)中獲取)并序列化成JSON返回。并把該文章列表存入緩存之中。

接下來(lái)實(shí)現(xiàn)第二個(gè)接口,通過(guò)文章ID來(lái)查詢(xún), 實(shí)現(xiàn)參考代碼如下:

// 獲取單篇文章
func GetArticle(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  params := mux.Vars(r)

  // 嘗試從緩存中獲取單個(gè)文章
  if cachedArticle, found := articleCache.Load(params["id"]); found {
    json.NewEncoder(w).Encode(cachedArticle)
    return
  }

  // 從原始數(shù)據(jù)源獲取單個(gè)文章
  for _, article := range Articles {
    if article.ID == params["id"] {
      json.NewEncoder(w).Encode(article)
      // 將單個(gè)文章存入緩存
      articleCache.Store(params["id"], article)
      return
    }
  }
  json.NewEncoder(w).Encode(&Article{})
}

首先將傳入的ID參數(shù)在緩存中進(jìn)行查找, 找到則直接返回JSON數(shù)據(jù)。如果沒(méi)有找到則繼續(xù)在文章列表中查找, 并將單篇文章存入緩存。

創(chuàng)建文章接口參考代碼如下:

// 創(chuàng)建文章
func CreateArticle(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  var article Article
  _ = json.NewDecoder(r.Body).Decode(&article)
  Articles = append(Articles, article)

  // 清除所有文章緩存
  articleCache.Delete("all")

  json.NewEncoder(w).Encode(Articles)
}

創(chuàng)建文章列表需要注意的是, 這里為了維護(hù)緩存一致性,避免臟數(shù)據(jù), 對(duì)緩存進(jìn)行了清空, 以便下次GetArticles()時(shí)更新最新的緩存。

同理也不難實(shí)現(xiàn)刪除文章的接口:

// 刪除文章
func DeleteArticle(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  params := mux.Vars(r)

  // 清除單個(gè)文章緩存
  articleCache.Delete(params["id"])

  for index, article := range Articles {
    if article.ID == params["id"] {
      Articles = append(Articles[:index], Articles[index+1:]...)
      break
    }
  }

  // 清除所有文章緩存
  articleCache.Delete("all")

  json.NewEncoder(w).Encode(Articles)
}

最后, 在main函數(shù)中, 我們需要往列表中添加一些數(shù)據(jù)來(lái)模擬服務(wù)端保存的文章數(shù), 并且定義四個(gè)接口的路由, 整體代碼如下:

package main

import (
  "encoding/json"
  "log"
  "net/http"
  "sync"

  "github.com/gorilla/mux"
)

// Article 結(jié)構(gòu)體表示 API 中的數(shù)據(jù)模型
type Article struct {
  ID string `json:"id,omitempty"`
  Title string `json:"title,omitempty"`
  Content string `json:"content,omitempty"`
}

// Articles 數(shù)組用于存儲(chǔ)文章數(shù)據(jù)
var Articles []Article
var articleCache sync.Map

// 獲取所有文章
func GetArticles(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")

  // 嘗試從緩存中獲取文章列表
  if cachedArticles, found := articleCache.Load("all"); found {
    json.NewEncoder(w).Encode(cachedArticles)
    return
  }

  // 從原始數(shù)據(jù)源獲取文章列表
  json.NewEncoder(w).Encode(Articles)

  // 將文章列表存入緩存
  articleCache.Store("all", Articles)
}

// 獲取單個(gè)文章
func GetArticle(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  params := mux.Vars(r)

  // 嘗試從緩存中獲取單個(gè)文章
  if cachedArticle, found := articleCache.Load(params["id"]); found {
    json.NewEncoder(w).Encode(cachedArticle)
    return
  }

  // 從原始數(shù)據(jù)源獲取單個(gè)文章
  for _, article := range Articles {
    if article.ID == params["id"] {
      json.NewEncoder(w).Encode(article)
      // 將單個(gè)文章存入緩存
      articleCache.Store(params["id"], article)
      return
    }
  }
  json.NewEncoder(w).Encode(&Article{})
}

// 創(chuàng)建文章
func CreateArticle(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  var article Article
  _ = json.NewDecoder(r.Body).Decode(&article)
  Articles = append(Articles, article)

  // 清除所有文章緩存
  articleCache.Delete("all")

  json.NewEncoder(w).Encode(Articles)
}

// 刪除文章
func DeleteArticle(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  params := mux.Vars(r)

  // 清除單個(gè)文章緩存
  articleCache.Delete(params["id"])

  for index, article := range Articles {
    if article.ID == params["id"] {
      Articles = append(Articles[:index], Articles[index+1:]...)
      break
    }
  }

  // 清除所有文章緩存
  articleCache.Delete("all")

  json.NewEncoder(w).Encode(Articles)
}


func main() {
  // 初始化數(shù)據(jù)
  Articles = append(Articles, Article{ID: "1", Title: "Article 1", Content: "Content 1"})
  Articles = append(Articles, Article{ID: "2", Title: "Article 2", Content: "Content 2"})

  // 創(chuàng)建路由器
  router := mux.NewRouter()

  // 定義路由處理程序
  router.HandleFunc("/articles", GetArticles).Methods(http.MethodGet)
  router.HandleFunc("/articles/{id}", GetArticle).Methods(http.MethodGet)
  router.HandleFunc("/articles", CreateArticle).Methods(http.MethodPost)
  router.HandleFunc("/articles/{id}", DeleteArticle).Methods(http.MethodDelete)

  // 啟動(dòng)服務(wù)器
  log.Fatal(http.ListenAndServe(":8080", router))
}

4.實(shí)際運(yùn)行效果

在本地運(yùn)行服務(wù)端, 服務(wù)端將在本地監(jiān)聽(tīng)8080端口, 通過(guò)瀏覽器輸入: http://127.0.0.1:8080/articles, 該接口將獲取所有文章,如圖:

通過(guò)API接口通過(guò)文章ID查詢(xún)某一篇文章,接口請(qǐng)求如下:

新增一條新文章是POST請(qǐng)求, 這里主要通過(guò)Apifox發(fā)送POST請(qǐng)求,如圖:

從返回的結(jié)果來(lái)看, 成功添加了一條新記錄, 再次使用獲取全部文章接口看一下,如圖:

新記錄確實(shí)添加成功。

最后, 還是通過(guò)Apifox,我們發(fā)送一個(gè)刪除ID為2的文章請(qǐng)求,如圖:

從Apifox返回的結(jié)果來(lái)看,確實(shí)刪除成功了,  現(xiàn)在再獲取一下全部文章,如圖:

所有接口全部驗(yàn)證成功。

責(zé)任編輯:趙寧寧 來(lái)源: 二進(jìn)制空間安全
相關(guān)推薦

2022-05-22 13:55:30

Go 語(yǔ)言

2023-04-10 14:20:47

ChatGPTRESTAPI

2024-01-02 12:17:44

Go傳統(tǒng)遠(yuǎn)程

2017-04-11 16:16:48

HTTPS互聯(lián)網(wǎng)服務(wù)端

2021-04-30 09:32:38

服務(wù)端渲染SSR

2024-01-08 08:36:29

HTTPGo代理服務(wù)器

2025-05-20 09:39:57

GogRPC微服務(wù)

2024-04-01 13:18:15

App架構(gòu)服務(wù)端

2023-09-11 10:53:32

2022-06-14 15:07:04

IPC客戶(hù)端服務(wù)端

2023-08-01 07:25:38

Expresso框架API

2014-04-14 15:54:00

print()Web服務(wù)器

2022-03-06 19:57:50

狀態(tài)機(jī)easyfsm項(xiàng)目

2014-06-12 14:52:52

python服務(wù)器

2023-05-10 08:05:41

GoWeb應(yīng)用

2017-09-07 12:35:39

前端JavascriptNode.js

2016-10-09 08:35:09

Linux桌面REST

2020-07-03 10:21:48

Go框架Docker

2011-09-09 09:44:23

WCF

2012-12-07 10:15:53

IBMdW
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 在线婷婷| 91中文视频 | 久久一区二区三区四区 | 欧美精品久久久 | av一级久久 | 黄色三级免费网站 | 国产精品精品视频 | 久久久高清 | 亚洲精品一 | 视频第一区 | 亚洲天堂精品久久 | 国产精品视屏 | 亚洲精品字幕 | 99国产视频| 天堂免费 | 国产精品一二区 | 99久久久国产精品免费消防器 | 日本一区二区三区视频在线 | 欧美亚洲视频 | 7777在线视频免费播放 | 五月激情六月婷婷 | 亚洲一区二区三区在线视频 | 亚洲国产精品成人久久久 | 国产精品久久777777 | www国产成人免费观看视频,深夜成人网 | 黄色电影在线免费观看 | 亚洲国产中文字幕 | 国产精品国产精品国产专区不卡 | 99re6热在线精品视频播放 | 欧美日韩淫片 | www.久久.com | 日韩国产在线 | 国产一二三区在线 | av网站在线看 | 日本午夜一区二区三区 | 在线免费观看黄色 | 亚洲男人天堂网 | 中文字幕视频一区 | 色久电影 | 久久久精品一区 | 亚洲一区视频在线 |