原文地址javascript
近年來NODEJS發展迅速,不少工程師尤爲是前端工程師,用NODEJS來開發一些後端應用。同時,研發效率和研發成本成爲開發者關注的重點,對於一些基礎經常使用功能,如何避免重複開發,成爲你們關注的重點,而 Parse Server 就是抽象了經常使用功能的NODEJS開源項目。html
首先,從總體上看看 Parse Server
提供了哪些基礎功能:前端
默認狀況下,Parse Server 使用的默認數據庫是 MonogDB
,因此須要提早安裝該數據庫。關於數據庫的安裝與使用不是本文的重點,暫且跳過。java
const config = require('./config'); const app = express(); var api = new ParseServer({ databaseURI: config.databaseURI, cloud: './cloud/main.js', appId: config.appId, masterKey: config.masterKey, // push: { ... }, // See the Push wiki page // filesAdapter: ..., // 對應不一樣雲廠商的 FilesAdapter // javascriptKey: config.javascriptKey, // js客戶端認證 liveQuery: { // 創建websocket連接,實現實時通訊 classNames: ['Sdtuent'] } }); var dashboard = new ParseDashboard({ "apps": [ { "serverURL": "http://localhost:1337/parse", "appId": config.appId, "masterKey": config.masterKey, "appName": "test" }, ] }); // Serve the Parse API at /parse URL prefix app.use('/parse', api); app.use('/dashboard', dashboard); const port = 1337; const httpServer = http.createServer(app); httpServer.listen(port, function() { console.log('parse-server-example running on port ' + port + '.'); }); var parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer);
經過上述少許的代碼,快速完成服務的搭建,/parse
是API的前綴,/dashboard
是後臺的頁面路由前綴,這樣就能夠快速使用 Parse Server 提供的各類功能。git
針對不一樣環境、不一樣語言,parse server提供了大量的 SDK,本文以 javascript
爲例進行簡單介紹。github
<head> <script src="https://unpkg.com/parse@2.1.0/dist/parse.js"></script> </head> <body> ... <script> // 對應服務端設置的id Parse.initialize(${appId}, ${javascriptKey}); Parse.serverURL = 'http://127.0.0.1:1337/parse' const username = "xxx", password = 'xxxx'; const email = 'xxx' async function signup() { try { const user = new Parse.User; user.set('username', username); user.set('password', password); user.set('email', email); const result = await user.signUp(); console.log('result is: ', result); } catch(err) { console.log('error: ', err); } } signup(); </script> </body>
上面的示例,是在瀏覽器端進行用戶的註冊: 首先引入Javascript SDK
;而後進行基本的環境設置 Parse.initialize
、Parse.serverURL
;第三部就是使用SDK調用 user.signUp
完成註冊。web
而後到 dashboard
,能夠看到 user
中新增了一條記錄:數據庫
{ "results": [ { "objectId": "1r2sFIzSRP", "username": "xxx", "createdAt": "2019-02-16T10:30:00.070Z", "updatedAt": "2019-02-16T10:30:00.070Z", "ACL": { "*": { "read": true }, "1r2sFIzSRP": { "read": true, "write": true } } } ] }
Parse Server的權限控制分爲兩層: Class level permission(類級別的權限控制)、Object level access control(對象級別的權限控制)。express
async function saveData() { const Student = Parse.Object.extend("Student"); const student = new Student(); student.setACL(new Parse.ACL(Parse.User.current())); student.set("name", "小明"); student.set("age", 12); const result = await student.save(); console.log('save data: ', result); } async function getData() { const Student = Parse.Object.extend("Student"); const query = new Parse.Query(Student); query.equalTo('name', '小明'); const result = await query.find(); console.log('save data: ', result); } async function run() { await saveData(); await getData(); // 得到一條數據 await Parse.User.logOut(); // 用另一個帳號登陸 await getData(); // 結果爲空 }
上述示例設置了 Object level access control
,只有擁有該 object
權限的用戶,才能獲取對應的數據。後端
要實現數據的實時通訊,一般的作法是搭建一個websocket服務,客戶端與服務端創建長鏈接,這樣就能夠實現數據的實時通訊。Parse Server
也集成了這個功能,把websocket服務跟HTTP服務整合在一塊兒,便於 client 端統一調用。
由於 Parse Server 背後的數據存儲使用的是 MongoDB,數據格式是 schemaless 的, 可是這並非說能夠隨意寫入數據:
Class
的時候,能夠自定義字段及類型,同時默認添加 _id、_created_at、_updated_at、_acl 等字段_SCHEMA
集合,存儲了 Class 的格式信息,約束了數據再次寫入時的字段類型爲了驗證上述兩點,直接登陸 MongoDB
數據庫後臺:
// step1: 登陸數據庫後臺 mongo // step2: 查看 collection 狀況 show collections 結果以下: Student _Role _SCHEMA _Session _User // step3: 查看 _SCHEMA 內容 db.getCollection('_SCHEMA').find() 結果以下: { "_id":"Student", "objectId":"string", "updatedAt":"date", "createdAt":"date", "name":"string", "age":"number", "address":"string" } ...
接下來對Student表進行寫入操做,age的類型不是number,而使用string:
async function saveData() { const Student = Parse.Object.extend("Student"); const student = new Student(); student.setACL(new Parse.ACL(Parse.User.current())); student.set("name", "張三"); student.set("age", '9999'); student.set('address', '北京'); const result = await student.save(); console.log('save data: ', result); }
執行上述代碼,會拋出異常信息 schema mismatch for Student.age; expected Number but got String
若是進行業務開發,確定存在自定義的業務邏輯,Parse Server 一樣提供了對應的解決途徑。
先來看看 Cloud Code 是如何工做的:
// step1 在Parse Server入口處指定路徑 var api = new ParseServer({ ... cloud: './cloud/main.js', ... }); // step2 定義通常的Function Parse.Cloud.define("averageStars", async (request, response) => { const params = request.params; ... const result = ... response.success(result); }); // 定義hook函數 Parse.Cloud.beforeSave("Student", (request) => { ... }); // step3 客戶端調用自定義函數方式 async function invokeFn() { const params = { ... }; const ratings = await Parse.Cloud.run("averageStars", params); console.log('ratings: ', ratings); } // 客戶端出發hook比較簡單,對Student進行寫入,就會觸發hook函數 async function saveData() { const Student = Parse.Object.extend("Student"); const student = new Student(); ... const result = await student.save(); }
同時,Parse Server 也支持遠程調用,使用 Dashboard 的 Webhook功能,就能夠配置遠程調用API
Parse Server這個開源項目給了很多項目設計上的思考: