一 預備知識
預備知識:django的CBV和FBV
CBV(class based view):多用,簡單回顧一下
FBV(function based view):
CBV模式的簡單操作:來個登陸頁面吧
login.html檔案內容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
用戶名: <input type="text" name="username">
密碼: <input type="text" name="password">
<input type="submit">
</form>
</body>
</html>
url.py內容如下
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.LoginView.as_view(),name='login'),
]
views.py
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
from django.views import View
class LoginView(View):
def get(self,request):
return render(request,'login.html')
def post(self,request):
return HttpResponse('post')
大家還記得CBV的這個視圖函式,為什么get請求就能找到類的get方法,post請求就能找到post方法,其內部有個dispatch方法來進行分發,這又怎么玩呢,看原始碼啦,從哪里看呢?那里先執行,就從哪里看
views.LoginView.as_view()這個東西是不是先執行啊,url接收到請求,呼叫了它對不對,as_view()類方法,這個類方法給你回傳了一個叫view的方法,就是說這個url對應這個一個view方法,當用戶訪問login頁面的時候是不是就是執行了view(request),大家進去看看原始碼吧,
然后你就可以玩dispatch方法了,看代碼:
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
from django.views import View
class LoginView(View):
def dispatch(self, request, *args, **kwargs):
print('something...')
res = super().dispatch(request, *args, **kwargs) #注意,不用傳self,為什么呢,因為super已經幫你吧self放進去啦
print('someting....')
return res
def get(self,request):
return render(request,'login.html')
def post(self,request):
return HttpResponse('post')
為什么要說它呢,因為后面咱們的drf學習,就要用它啦,
二 restful規范
摘自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html
1. 什么是RESTFUl
RESTful 是目前最流行的 API 設計規范,用于 Web 資料介面的設計,
REST與技術無關,代表的是一種軟體架構風格,REST是Representational State Transfer的簡稱,中文翻譯為“表征狀態轉移”
REST從資源的角度類審視整個網路,它將分布在網路中某個節點的資源通過URL進行標識,客戶端應用通過URL來獲取資源的表征,獲得這些表征致使這些應用轉變狀態
所有的資料,不過是通過網路獲取的還是操作(增刪改查)的資料,都是資源,將一切資料視為資源是REST區別與其他架構風格的最本質屬性
對于REST這種面向資源的架構風格,有人提出一種全新的結構理念,即:面向資源架構(ROA:Resource Oriented Architecture)
另外還有其他兩種,簡單了解,
遠程程序呼叫(RPC)
遠程程序呼叫為 Web 服務提供一個分布式函式/方法介面供用戶呼叫,這是一種較傳統的方式,通常,在 WSDL 中對 RPC 介面進行定義(類似于早期的XML-RPC),本質上,RPC 方式利用一個簡單映射,把用戶請求直接轉化成一個特定語言撰寫的函式/方法,現在,該方式已不再使用,
面向服務架構(SOA)
面向服務架構現在,業界比較關注的是遵從面向服務架構(Service-oriented architecture,SOA)來構建 Web 服務,該方式中,通訊是由訊息驅動,而不再是某個動作(方法呼叫),這種 Web 服務也稱為“面向訊息的服務”,
網路應用程式,分為前端和后端兩個部分,當前的發展趨勢,就是前端設備層出不窮(手機、平板、桌面電腦、其他專用設備......),
因此,必須有一種統一的機制,方便不同的前端設備與后端進行通信,這導致API構架的流行,甚至出現"API First"的設計思想,RESTful API是目前比較成熟的一套互聯網應用程式的API設計理論,還有一篇《理解RESTful架構》,探討如何理解這個概念,
表征狀態轉移大概圖解:

2.RESTFUl API設計
2.1 使用協議
API與用戶的通信協議,總是使用HTTPs協議,
2.2 使用域名
應該盡量將API部署在專用域名之下,意思就是給API專門做一個服務器,
https://api.example.com
如果確定API很簡單,不會有進一步擴展,可以考慮放在主域名下,
https://example.org/api/
2.3 版本提示
網站的API可能一直在更新,那么應該將API的版本號放入URL,
https://api.example.com/v1/
另一種做法是,將版本號放在HTTP頭資訊中,但不如放入URL方便和直觀,Github采用這種做法,
2.4 路徑寫法
路徑又稱"終點"(endpoint),表示API的具體網址,
在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與資料庫的表格名對應,一般來說,資料庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應該使用復數,
舉例來說,有一個API提供動物園(zoo)的資訊,還包括各種動物和雇員的資訊,則它的路徑應該設計成下面這樣,
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
2.5 HTTP動詞
對于資源的具體操作型別,由HTTP動詞表示,請求方式時動詞,我們后端基于請求方式來分發對應的視圖函式來進行邏輯處理和資料處理、提取、加工等操作,但是URL中不能出現動詞,
常用的HTTP動詞有下面五個(括號里是對應的SQL命令),
GET(SELECT):從服務器取出資源(一項或多項),
POST(CREATE):在服務器新建一個資源,
PUT(UPDATE):在服務器更新資源(客戶端提供改變后的完整資源),
PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性,更新部分資源的意思),他和put用哪個都可以,沒有太大的區別,我們用put方式偏多
DELETE(DELETE):從服務器洗掉資源,
還有兩個不常用的HTTP動詞,
HEAD:獲取資源的元資料,
OPTIONS:獲取資訊,關于資源的哪些屬性是客戶端可以改變的
下面是一些例子,RESTful 的核心思想就是,客戶端發出的資料操作指令都是"動詞 + 賓語"的結構,比如,GET /articles這個命令,GET是動詞,/articles是賓語,根據 HTTP 規范,動詞一律大寫,
GET /zoos:列出所有動物園
POST /zoos:新建一個動物園
GET /zoos/ID:獲取某個指定動物園的資訊
PUT /zoos/ID:更新某個指定動物園的資訊(提供該動物園的全部資訊)
PATCH /zoos/ID:更新某個指定動物園的資訊(提供該動物園的部分資訊)
DELETE /zoos/ID:洗掉某個動物園
GET /zoos/ID/animals:列出某個指定動物園的所有動物
DELETE /zoos/ID/animals/ID:洗掉某個指定動物園的指定動物
動詞覆寫:
有些客戶端只能使用GET和POST這兩種方法,服務器必須接受POST模擬其他三個方法(PUT、PATCH、DELETE),
這時,客戶端發出的 HTTP 請求,要加上X-HTTP-Method-Override屬性,告訴服務器應該使用哪一個動詞,覆寫POST方法,
POST /api/Person/4 HTTP/1.1
X-HTTP-Method-Override: PUT
上面代碼中,X-HTTP-Method-Override指定本次請求的方法是PUT,而不是POST,
賓語必須是名字:
賓語就是 API 的 URL,是 HTTP 動詞作用的物件,它應該是名詞,不能是動詞,比如,/articles這個 URL 就是正確的,而下面的 URL 不是名詞,所以都是錯誤的,
/getAllCars
/createNewCar
/deleteAllRedCars
既然 URL 是名詞,那么應該使用復數,還是單數?
這沒有統一的規定,但是常見的操作是讀取一個集合,比如GET /articles(讀取所有文章),這里明顯應該是復數,
為了統一起見,建議都使用復數 URL,比如GET /articles/2要好于GET /article/2,

2.6 過濾資訊(filtering,或稱查詢引數)
如果記錄數量很多,服務器不可能都將它們回傳給用戶,API應該提供引數,過濾回傳結果,
下面是一些常見的引數,
?limit=10:指定回傳記錄的數量
?offset=10:指定回傳記錄的開始位置,
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數,
?sortby=name&order=asc:指定回傳結果按照哪個屬性排序,以及排序順序,
?animal_type_id=1:指定篩選條件
引數的設計允許存在冗余,即允許API路徑和URL引數偶爾有重復,比如,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的,
常見的情況是,資源需要多級分類,因此很容易寫出多級的 URL,比如獲取某個作者的某一類文章,
GET /authors/12/categories/2
這種 URL 不利于擴展,語意也不明確,往往要想一會,才能明白含義,
更好的做法是,除了第一級,其他級別都用查詢字串表達,
GET /authors/12?categories=2
下面是另一個例子,查詢已發布的文章,你可能會設計成下面的 URL,
GET /articles/published
查詢字串的寫法明顯更好
GET /articles?published=true
2.7 狀態碼
2.7.1 狀態碼必須精確
客戶端的每一次請求,服務器都必須給出回應,回應包括 HTTP 狀態碼和資料兩部分,
HTTP 狀態碼就是一個三位數,分成五個類別,
1xx:相關資訊
2xx:操作成功
3xx:重定向
4xx:客戶端錯誤
5xx:服務器錯誤
這五大類總共包含100多種狀態碼,覆寫了絕大部分可能遇到的情況,每一種狀態碼都有標準的(或者約定的)解釋,客戶端只需查看狀態碼,就可以判斷出發生了什么情況,所以服務器應該回傳盡可能精確的狀態碼,
API 不需要1xx狀態碼,下面介紹其他四類狀態碼的精確含義,
2.7.2 2xx狀態碼
200狀態碼表示操作成功,但是不同的方法可以回傳更精確的狀態碼,
GET: 200 OK
POST: 201 Created
PUT: 200 OK
PATCH: 200 OK
DELETE: 204 No Content
上面代碼中,POST回傳201狀態碼,表示生成了新的資源;DELETE回傳204狀態碼,表示資源已經不存在,
此外,202 Accepted狀態碼表示服務器已經收到請求,但還未進行處理,會在未來再處理,通常用于異步操作,下面是一個例子,
HTTP/1.1 202 Accepted
{
"task": {
"href": "/api/company/job-management/jobs/2130040",
"id": "2130040"
}
}
2.7.3 3xx狀態碼
API 用不到301狀態碼(永久重定向)和302狀態碼(暫時重定向,307也是這個含義),因為它們可以由應用級別回傳,瀏覽器會直接跳轉,API 級別可以不考慮這兩種情況,
API 用到的3xx狀態碼,主要是303 See Other,表示參考另一個 URL,它與302和307的含義一樣,也是"暫時重定向",區別在于302和307用于GET請求,而303用于POST、PUT和DELETE請求,收到303以后,瀏覽器不會自動跳轉,而會讓用戶自己決定下一步怎么辦,下面是一個例子,
HTTP/1.1 303 See Other
Location: /api/orders/12345
2.7.4 4xx狀態碼
4xx狀態碼表示客戶端錯誤,主要有下面幾種,
400 Bad Request:服務器不理解客戶端的請求,未做任何處理,
401 Unauthorized:用戶未提供身份驗證憑據,或者沒有通過身份驗證,
403 Forbidden:用戶通過了身份驗證,但是不具有訪問資源所需的權限,
404 Not Found:所請求的資源不存在,或不可用,
405 Method Not Allowed:用戶已經通過身份驗證,但是所用的 HTTP 方法不在他的權限之內,
410 Gone:所請求的資源已從這個地址轉移,不再可用,
415 Unsupported Media Type:客戶端要求的回傳格式不支持,比如,API 只能回傳 JSON 格式,但是客戶端要求回傳 XML 格式,
422 Unprocessable Entity :客戶端上傳的附件無法處理,導致請求失敗,
429 Too Many Requests:客戶端的請求次數超過限額,
2.7.5 5xx狀態碼
5xx狀態碼表示服務端錯誤,一般來說,API 不會向用戶透露服務器的詳細資訊,所以只要兩個狀態碼就夠了,
500 Internal Server Error:客戶端請求有效,服務器處理時發生了意外,
503 Service Unavailable:服務器無法處理請求,一般用于網站維護狀態,
總結一下常用狀態碼及對應的描述
200 OK - [GET]:服務器成功回傳用戶請求的資料,該操作是冪等的(Idempotent),
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改資料成功,
202 Accepted - [*]:表示一個請求已經進入后臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶洗掉資料成功,301 狀態碼(永久重定向)302 狀態碼(暫時重定向,307也是這個含義)
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改資料的操作,該操作是冪等的,
401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤),
403 Forbidden - [*] 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的,
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的,
406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式),
410 Gone -[GET]:用戶請求的資源被永久洗掉,且不會再得到的,
422 Unprocesable entity - [POST/PUT/PATCH] 當創建一個物件時,發生一個驗證錯誤,
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將無法判斷發出的請求是否成功,
更多看這里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
2.8 服務器回應
2.8.1 回應資料格式
API 回傳的資料格式,不應該是純文本,而應該是一個 JSON 物件,因為這樣才能回傳標準的結構化資料,所以,服務器回應的 HTTP 頭的Content-Type屬性要設為application/json,
客戶端請求時,也要明確告訴服務器,可以接受 JSON 格式,即請求的 HTTP 頭的ACCEPT屬性也要設成application/json,下面是一個例子,
GET /orders/2 HTTP/1.1
Accept: application/json
2.8.2 發生錯誤時的回應
發生錯誤時不要回應200狀態碼,有一種不恰當的做法是,即使發生錯誤,也回傳200狀態碼,把錯誤資訊放在資料體里面,就像下面這樣,
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "failure",
"data": {
"error": "Expected at least two items in list."
}
}
上面代碼中,決議資料體以后,才能得知操作失敗,
這張做法實際上取消了狀態碼,這是完全不可取的,正確的做法是,狀態碼反映發生的錯誤,具體的錯誤資訊放在資料體里面回傳,下面是一個例子,
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Invalid payoad.",
"detail": {
"surname": "This field is required."
}
}
2.8.3 回應結果
針對不同操作,服務器向用戶回傳的結果應該符合以下規范,
GET /collection:回傳資源物件的串列(陣列),一般是[{"id":1,"name":"a",},{"id":2,name:"b"},]這種型別
GET /collection/resource:回傳單個資源物件, 一般是查看的單條資料 {"id":1,"name":'a'}
POST /collection:回傳新生成的資源物件 , 一般是回傳新添加的資料資訊, 格式一般是{}
PUT /collection/resource:回傳完整的資源物件 一般時回傳更新后的資料,{}
PATCH /collection/resource:回傳完整的資源物件
DELETE /collection/resource:回傳一個空檔案 一般回傳一個空字串
例如:

2.9 Hypermedia API,提供鏈接
RESTful API最好做到Hypermedia,即回傳結果中提供鏈接,API 的使用者未必知道,URL 是怎么設計的,一個解決方法就是,在回應中,給出相關鏈接,便于下一步操作,這樣的話,用戶只要記住一個 URL,就可以發現其他的 URL,這種方法叫做 HATEOAS,
舉例來說,GitHub 的 API 都在 api.github.com 這個域名,訪問它,就可以得到其他 URL,
{
...
"feeds_url": "https://api.github.com/feeds",
"followers_url": "https://api.github.com/user/followers",
"following_url": "https://api.github.com/user/following{/target}",
"gists_url": "https://api.github.com/gists{/gist_id}",
"hub_url": "https://api.github.com/hub",
...
}
上面的回應中,挑一個 URL 訪問,又可以得到別的 URL,對于用戶來說,不需要記住 URL 設計,只要從 api.github.com 一步步查找就可以了,
HATEOAS 的格式沒有統一規定,上面例子中,GitHub 將它們與其他屬性放在一起,更好的做法應該是,將相關鏈接與其他屬性分開,
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "In progress",
"links": {[
{ "rel":"cancel", "method": "delete", "href":"/api/status/12345" } ,
{ "rel":"edit", "method": "put", "href":"/api/status/12345" }
]}
}
再比如:當用戶向api.example.com的根目錄發出請求,會得到這樣一個檔案,
{"link": {
"rel": "collection https://www.example.com/zoos",
"href": "https://api.example.com/zoos",
"title": "List of zoos",
"type": "application/vnd.yourformat+json"
}}
上面代碼表示,檔案中有一個links屬性,用戶讀取這個屬性就知道下一步該呼叫什么API了,rel表示這個API與當前網址的關系(collection關系,并給出該collection的網址),href表示API的路徑,title表示API的標題,type表示回傳型別,
2.10 其他
(1)API的身份認證應該使用OAuth 2.0框架,
(2)服務器回傳的資料格式,應該盡量使用JSON,避免使用XML,
三 Django RestFramework(簡稱DRF)
drf是django發展來的一個符合restful介面規范的一個東西,啥東西呢,就是django的一個app,還記得app是啥不,DRF官網地址,但是大家記住一句話,即便是沒有這drf,我們照樣能做前后端分離的專案,自己做規范的資料介面,回傳json資料,都是沒問題的昂,那為什么還用drf啊,這個更nb,
在官網中我們看一下這里:

首先下載安裝,django是必須要的,不過咱們的django已經下載好了,如果沒下載好,那么pip install django,執行一下:
pip install django
pip install djangorestframework //執行這句話,下載drf
# Set up a new project with a single application
django-admin startproject tutorial . # Note the trailing '.' character
cd tutorial
django-admin startapp quickstart
cd ..
1.先基于djangoCBV,不用DRF來寫個介面,看看效果
好,接下來我們創建一個django專案,models中創建一個表,添加一些資料,然后寫一個資料介面來獲取一下這些資料,回傳json資料型別,按照我們CBV的模式來寫,但是下面還沒有用到我們的drf昂,只是告訴大家,沒有drf,你也能做,


views.py檔案內容如下:
from django.shortcuts import render,HttpResponse,redirect
import json
# Create your views here.
from django.views import View
from app01 import models
class CourseView(View):
def get(self,request):
#拿到queryset型別的資料,要加工成[{},{}]這種資料型別
course_obj_list = models.Course.objects.all()
ret = []
for course_obj in course_obj_list:
ret.append({
"title":course_obj.title,
"desc":course_obj.desc,
})
return HttpResponse(json.dumps(ret,ensure_ascii=False)) #ensure_ascii=False是告訴json不要對中文進行編碼,不然回傳給前端的資料中如果有中文的話會被編碼成unicode型別的資料,導致前端看不到中文
urls.py內容如下:
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
#url(r'^admin/', admin.site.urls),
url(r'^courses/', views.CourseView.as_view(),name='courses'), #介面就寫好啦
]
然后啟動專案,在瀏覽器中一訪問,就看到了我們后端回傳的json資料:

有人就又說了,我們這么寫也ok啊,要drf干嘛,上面這個例子是個簡單的例子,資料簡單、邏輯簡單,你這樣寫當然看著沒有問題啦,但是資料量很大,結構很復雜的時候,你這樣寫的時候就頭疼了,
所以上面這個例子你就作為了解吧,我們玩一下drf,
玩DRF之前,我們先說一下我們DRF中有哪些內容:
咱們玩下面10個組件: a.APIView (*****)
b.序列化組件 (*****)
c.試圖類(mixin) (*****)
d.認證組件 (*****)
e.權限組件
f.頻率組件
g.分頁組件
h.決議器組件 (*****)
i.相應其組件
j.url控制器
2.基于DRF來寫介面
2.1 APIView組件
在我們的視圖中,通過CBV來寫視圖的時候,繼承APIView,url不變,還是上面那個,通過瀏覽器訪問,照樣能夠看到我們回傳的資料,
views.py內容如下:
from django.shortcuts import render,HttpResponse,redirect
import json
from django.views import View
from app01 import models
#引入APIView,APIView是繼承的django的View,也就是APIView在View的基礎上添加了一些其他的功能
from rest_framework.views import APIView
class CourseView(APIView):
def get(self,request):
course_obj_list = models.Course.objects.all()
ret = []
for course_obj in course_obj_list:
ret.append({
"title":course_obj.title,
"desc":course_obj.desc,
})
return HttpResponse(json.dumps(ret, ensure_ascii=False))
urls.py內容如下:
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^courses/', views.CourseView.as_view(),name='courses'),
]
頁面訪問url效果:

照樣拿到了資料,那么怎么回事兒呢,我們看原始碼,知道一下APIView的流程就行,
2.2 決議器組件
知識準備,還記得一個叫做contentType的http請求頭的東西嗎?回想一下,

后端根據contentType的型別來找到對應的決議資料的方法來決議資料,提取資料

但是django沒有內置的自動解開json資料型別的方法,那么只能去request.body里面拿原始的bytes型別的資料,然后自己解,其實很簡單,但是django沒有,可能是早先沒有考慮到,

django自動通過contentType來決議資料的那些方法就叫做django的決議器,能解的是urlencode和檔案的那個mutipart/form-data型別的資料,然后將資料放到了request.POST方法里面,
def post(self,request):
print(request.POST)
print(type(request)) #通過這個物件的型別(類物件),找到它的原始碼看看
return HttpResponse('POST')
而DRF通過自己的決議器,幫我們給request里面封裝了一個request.data屬性,獲取請求體里面的資料,然后決議,并且這個決議器基本上能夠決議所有的資料型別,包括django不能自動決議的json資料型別,我們通過Postman(關于Postman工具的使用,看下面那個章節)來除錯一下,看看效果

def post(self,request):
print(request.data) #列印結果是:{'name': 'chao'}
return HttpResponse('POST')
我們接著往下看:首先我們給我們的試圖類添加一個類變數,這些類變數是用來控制我們視圖類里面的各個組件

看一下代碼:
from django.shortcuts import render,HttpResponse,redirect
import json
from django.views import View
from app01 import models
from rest_framework.views import APIView
#匯入決議器
from rest_framework.parsers import JSONParser,FormParser,MulTiPartParser
# JSONParser:決議json資料的額
# FormParser:決議urlencoded資料的
# FileUploadParser:決議檔案資料的
class CourseView(APIView):
#寫一個類屬性,名字必須是parser_classes
parser_classes = [JSONParser,] #里面存放我們上面匯入的那幾個決議器,如果我們里面寫了一個JSONParser,那么決議器只能決議前端發送過來的json資料,存放到request.data里面,可以通過postman測驗一下看看效果,為什么?看原始碼吧
def get(self,request):
course_obj_list = models.Course.objects.all()
ret = []
for course_obj in course_obj_list:
ret.append({
"title":course_obj.title,
"desc":course_obj.desc,
})
return HttpResponse(json.dumps(ret, ensure_ascii=False))
def post(self,request): print('ok') #你會發現,即便是發送的資料型別不對,post方法也走了,但是request.data沒有東西,那么肯定是它出了問題
print(request.data) #request.data對我們的資料進行決議的,那么說明data不是一個變數,而是一個屬性方法,還記得屬性方法嗎
return HttpResponse('POST')
原始碼看著比較復雜,這里我就不列舉了,反正你要知道的是,我們的決議器的查找使用順序是:
自己寫的類里面的parser_classes = [JSONParser,]---->然后找settings中的----->然后找默認的,只要找到,就用了,其他的組件也都是這么個順序,所以其他的咱們就不看了,
四 Postman的使用
Postman是一個模擬發送請求并獲得回應結果的工具,不用這個工具的時候,我們寫web專案,除錯介面回傳資料的時候,是不是都要啟動專案,通過瀏覽器訪問,然后查看資料啊,有了這個工具我們就可以不用啟動瀏覽器來,通過這個工具就能進行除錯,首先下載安裝
下載地址:https://www.getpostman.com/downloads/
安裝,然后使用,直接看圖吧,一看就明白:


轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/32424.html
標籤:架構設計
上一篇:日志審計系統設計
下一篇:樂觀鎖和悲觀鎖的一個例子
