[Python Django] rest-framework與drf_yasg如何規劃api版本

最近在做Restful API的建立,故有些東西先記錄下來,避免日後忘記,所以這邊不會去細講Django的rest-framework與其套件drf_yasg,僅針對一些設定記錄下來.

由於在建立API時,可能因為產品與時間的迭代,會出現好幾個版本的API,但要怎麼明確讓使用者知道使用哪隻API,又可以讓過去已經使用API的人還可以使用舊有的API這就在設計的時候需要思考的,當然設計的方式有很多種,這邊我將只是透過django的路由機制來進行調整.

1.規劃想法

未來使用者,使用的API URL為類似

http://localhost:8888/api/v1/action1

http://localhost:8888/api/v2/action1

所以需要產生v1與v2版本的API,路由分別為

v1/action1
v1/action2

v2/action1
v2/action2

2.為了避免錯亂,我先將專案架構列出來會比較清楚(注意紅色區塊即可)

專案樹狀結構

專案樹狀結構

3.先設定一下v1的路由(api/urls.py)

from django.urls import path
from .views.v1 import views_v1
urlpatterns = [
	path('v1/action1', views_v1.action1.as_view(), name='v1action1'),
	path('v1/action2', views_v1.action2.as_view(), name='v1action2'),
]

4.記得要把view也加上喔!(api/views/v1/views_v1.py),因為這邊不是在說明drf_yasg,所以這邊我就不特別說明views怎麼寫

from drf_yasg.utils import swagger_auto_schema
from rest_framework.generics import GenericAPIView
class action1(GenericAPIView):
	#swagger_tags = ["v1"]
	@swagger_auto_schema(
		responses='',
		operation_summary='v1 action1',
		operation_description='POST v1/action1',
	)

	def post(self, request, *args, **kwargs):
                 pass

		
class action1(GenericAPIView):
	#swagger_tags = ["v1"]
	@swagger_auto_schema(
		responses='',
		operation_summary='v1 action2',
		operation_description='POST v1/action2',
	)

	def post(self, request, *args, **kwargs):
                 pass

 

5.測試一下

只有v1的swagger

只有v1的swagger

6.基本上v1版本的API就建立好了,但由步驟4可以注意紅框的地方,套件會自動帶出Base URL,筆者測試的時候,以為如果建立好v2會不會Base URL都停留在/api/v1上?

7.讓我們繼續看下去,將v2版本的API也設定上去吧,先加上路由(api/urls.py)

from django.urls import path
from .views.v1 import views_v1
from .views.v2 import views_v2
urlpatterns = [
	path('v1/action1', views_v1.action1.as_view(), name='v1action1'),
	path('v1/action2', views_v1.action2.as_view(), name='v1action2'),
	path('v2/action1', views_v2.action1.as_view(), name='v2action1'),
	path('v2/action2', views_v2.action2.as_view(), name='v2action2')
]

8.記得要把view也加上喔!(api/views/v2/views_v2.py),這次是加v2別搞錯噢!!因為這邊不是在說明drf_yasg,所以這邊我就不特別說明views怎麼寫

from drf_yasg.utils import swagger_auto_schema
from rest_framework.generics import GenericAPIView
class action1(GenericAPIView):
	#swagger_tags = ["v2"]
	@swagger_auto_schema(
		responses='',
		operation_summary='v2 action1',
		operation_description='POST v2/action1',
	)

	def post(self, request, *args, **kwargs):
                 pass

		
class action1(GenericAPIView):
	#swagger_tags = ["v2"]
	@swagger_auto_schema(
		responses='',
		operation_summary='v2 action2',
		operation_description='POST v2/action2',
	)

	def post(self, request, *args, **kwargs):
                 pass

9.來看看變成如何!神奇的事情發生了,剛剛步驟6筆者擔心的地方,套件自己改變了,會自動轉為/api這樣就不會錯亂了!

v1:v2的swagger

v1:v2的swagger

10.後記

-採用版本

python 3.7.4
django 3.2.3
djangorestframework 3.12.2
drf-yasg 1.20.0

-可以看到步驟9系統會依據版本幫您分類,如果沒有出現可能是因為套件版本,可以這麼做

A.在專案底下建立一個資料夾config,裡面建立一個swagger.py,覆寫SwaggerAutoSchema

from drf_yasg.inspectors import SwaggerAutoSchema
class CustomSwaggerAutoSchema(SwaggerAutoSchema):
    def get_tags(self, operation_keys=None):
        operation_keys = operation_keys or self.operation_keys

        tags = self.overrides.get('tags')
        if not tags:
            tags = [operation_keys[0]]
        if hasattr(self.view, "swagger_tags"):
            tags = self.view.swagger_tags

        return tags

B.在每個view加入版本資訊,以api/v1/views_v1.py為例

from drf_yasg.utils import swagger_auto_schema
from rest_framework.generics import GenericAPIView
class action1(GenericAPIView):
	swagger_tags = ["v1"] #主要加入此行產生聚合效果
	@swagger_auto_schema(
		responses='',
		operation_summary='v1 action1',
		operation_description='POST v1/action1',
	)

	def post(self, request, *args, **kwargs):
                 pass

		
class action1(GenericAPIView):
	swagger_tags = ["v1"] #主要加入此行產生聚合效果
	@swagger_auto_schema(
		responses='',
		operation_summary='v1 action2',
		operation_description='POST v1/action2',
	)

	def post(self, request, *args, **kwargs):
                 pass

C.修改專案setting.py,加入以下,重啟專案應該就會分類了

SWAGGER_SETTINGS = {
    'DEFAULT_AUTO_SCHEMA_CLASS': 'config.swagger.CustomSwaggerAutoSchema',
}

11.連文件都可以依據版本分類喔!

文件依據版本分類

文件依據版本分類

12.補充

-後來在測試會不會依據版本分類,發現只有v1版的時後,系統會將api每一隻拆開,但當有v2後,就會聚合v1一組v2一組,不需要再加上步驟10,除非想要只有v1也產生聚合效果才要加!

–只有v1的樣子

只有v1的swagger

只有v1的swagger

–只有v1又想要有聚合效果

v1又具備聚合效果

v1又具備聚合效果

–v1與v2同時存在

v1:v2的swagger

v1:v2的swagger

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *