之前半年時間,來到項目的時候,已經有一些東西,大致就是IIS+MYSQL+PHP.
所以接着做,修修補補,Android/iOS與服務器數據庫交換用PHP, Web那邊則是JS+PHP,也沒有前后端之分。本身並不是計算機方向的,所以也沒有對這個框架做改動。可能本身沒有用PHP的一些框架,總覺得寫起來不是很爽快。
接下來的項目開始略有變化,因為我先開始做的一塊,並不是直接做到C,而是后面可能會與其他部分存在數據交換(主要是從我這邊獲取數據),基於興趣,也基於前后端分離的概念,因為后面可能會有有移動端和Web端都需要,所以我決定做一個RESTful的后端。
經過簡單的學習就直接上手,利用Python Flask+Mysql+SqlAlchemy搭建一個后端(后面根據需要可能加上Redis),目前也還在完善中,寫下來筆記先,錯漏和理解錯誤在所難免,繼續學習。
越來越覺得,Google/Baidu的搜索功能下,很多細節我不太願意記錄。很多時候的問題在於,你想實現一個功能的時候不太會描述你的問題(keyword),當然跨方向可能就是有這個問題,專業詞匯不熟悉。所以我努力記錄下一些概念,思路和關鍵詞。
1.前后端分離
之前做過的小項目里面,最早時候直接PHP直接對mysql操作,組織混亂(隨意在需要的地方增加代碼),改了一個地方可能很多地方都受影響:
比如說一張表的結構發生變化,那么可能整個代碼里面對於該表有操作的地方,都需要找出來修改,這實在是非常危險的行為,也付出了不少代價。我后來將所有對於Mysql的操作都整理到一個php文件里面來調用稍微緩解了一下這個問題,不過依然不太滿意。不過這個本身可能是我php代碼現學現用,很多時間都在趕進度造成的問題.
同時項目開始的時候也沒有很統一的異常、錯誤處理規范,項目本身已經非常小,兩三個人做起來溝通都非常麻煩。
同時這種簡單組織的方式,在iOS,Android,和Web同時做起來的時候,也感覺一團亂麻。
所以最終,在這個機會,我稍微學習(繼續學習ing)想對新的這一部分,完全做到前后分離。
因為目前來講,項目的並發壓力不大,所以決定利用輕量級的Flask搭建一個后端來處理所有數據交互,那么到底用什么樣的方式交互呢?
2.Why RESTful
RESTful是一種風格,定義如何利用HTTP本身的方法GET/POST/PUT/DELTE/PATCH等來定義行為(CRUD),而用層級的資源表示(URI)來明確的標明服務器資源之間的關系。客戶端無論是iOS/Web/Android, 遵循這個規范對資源進行訪問,既保證了安全性同時十分容易管理。
當然RESTful用什么都可以,比如說Node.js, 雖然我本身有Java經驗但是對於js的掌握程度一般,所以沒有采用。
3.
HATEOAS
除了上面的非常簡單的說明,其實RESTful還有個重要的概念叫做
HATEOAS(
Hypermedia As The Engine Of Application State ), 大致意思,是客戶端與服務器的交互,其實我們平時可以看到,很多公司提供RESTful API, 則會有API文檔,詳細定義了API的endpoint, 規則等。那么假如修改API,則需要修訂API文檔,所有利用該API的服務可能都需要修改,所以有時候v1/v2這樣子來管理不同版本的API, 但是HATEOAS則推崇利用超本文實現資源的導航,大部分時候不需要去查詢文檔就能使用API,你只需要知道一個根API.
GitHub的API就很高程度的實現這種類型的API.(參見: https://api.github.com),是不是不需要文檔也基本能找到自己想要的資源在哪里,非常值得參考。
這樣的動態資源獲取,當你的API改變的時候,也能減小影響范圍。
{
"current_user_url": "https://api.github.com/user",
"current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
"authorizations_url": "https://api.github.com/authorizations",
"code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
"commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
"emails_url": "https://api.github.com/user/emails",
"emojis_url": "https://api.github.com/emojis",
"events_url": "https://api.github.com/events",
"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",
"issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}",
"issues_url": "https://api.github.com/issues",
"keys_url": "https://api.github.com/user/keys",
"notifications_url": "https://api.github.com/notifications",
"organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}",
"organization_url": "https://api.github.com/orgs/{org}",
"public_gists_url": "https://api.github.com/gists/public",
"rate_limit_url": "https://api.github.com/rate_limit",
"repository_url": "https://api.github.com/repos/{owner}/{repo}",
"repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
"current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}",
"starred_url": "https://api.github.com/user/starred{/owner}{/repo}",
"starred_gists_url": "https://api.github.com/gists/starred",
"team_url": "https://api.github.com/teams",
"user_url": "https://api.github.com/users/{user}",
"user_organizations_url": "https://api.github.com/user/orgs",
"user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}",
"user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"
}
當然,我想這種方式可能對於獲取資源特別有用,但是對於
更新和創建資源,還是要參考文檔的,因為涉及到較多的參數傳遞。說道參數傳遞,我看到的基本都用json來進行數據交換。
4.SQLAlchemy
之前利用php mysql對數據庫進行直接操作,數據一致性檢查和處理對我來講都不太友好。轉到Python后測試SQLalchemy之后簡直如發現了新大陸,對數據庫的操作和結構修改都容易了很多。雖說有人詬病其效率,但是我目前的項目需求來講,完全不構成問題。
SQLAlchemy是ORM( Object Relational Mapper)的數據庫操作包,假如你對數據結構的一對多,多對多,一對一等基本關系理解深刻,配合SLQAlchemy使用則如魚得水,大大簡化對數據庫的操作和安全檢查。
5.認證和權限管理
設計一個API,當然要考慮權限管理保證安全性需要,至於是用戶/密碼認證還是token, 利用python的decorator都能容易的實現。當然,如果設計到RBAC(Role based access control)來區分用戶對於具體資源的操作權限進行限制可能稍微麻煩一些。
6.Flask-Restful
本身利用Flask做restful API也ok, 但是Flask-Restful提供了更好用更簡單的框架,讓你更加輕易的實現你的Restful API. 官方文檔也非常的簡短易讀。我本身特別喜歡的是其利用Output Fields 對你的資源輸出進行管理的方式。
