Parse Server - 快速實現 Serverless 平臺的利器

原文地址javascript

圖片描述

近年來NODEJS發展迅速,不少工程師尤爲是前端工程師,用NODEJS來開發一些後端應用。同時,研發效率和研發成本成爲開發者關注的重點,對於一些基礎經常使用功能,如何避免重複開發,成爲你們關注的重點,而 Parse Server 就是抽象了經常使用功能的NODEJS開源項目。html

首先,從總體上看看 Parse Server 提供了哪些基礎功能:前端

  • 用戶的登陸註冊
  • 用戶身份的認證
  • 數據存儲 && 靈活查詢
  • 文件存儲
  • 實時查詢
  • 消息推送
  • 緩存服務
  • 與雲平臺很好的對接
  • 自定義業務邏輯與Hook機制

服務快速搭建

默認狀況下,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.initializeParse.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 端統一調用。

圖片描述

Class的schema問題

由於 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

Cloud Code / HOOK 機制 - 實現自定義業務邏輯

若是進行業務開發,確定存在自定義的業務邏輯,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這個開源項目給了很多項目設計上的思考:

  • 具體功能抽象,把一些經常使用功能抽象出來,是研發提效的一個很重要的手段
  • server + client模式,抽象出業務模型以後,若是隻是解決了某一部分的問題(例如server),使用成本依然很高,可是若是解決更多鏈路上的問題,那就會變得更加容易使用和落地。Parser Server不只提供了server端的實現,並且提供了Dashboard、Client、Adapter等內容
  • hook功能,用於解決個性化需求,知足業務定製
  • 與雲的結合,目前已成爲將來技術選型的一個很大趨勢,Parse Server 的文件存儲,提供了不少雲存儲相關的 Adapter,快速實現跟雲產品的對接
  • 權限控制設計,數據的安全已經成爲研發很重要的一個工做,分級控制是個思路
相關文章
相關標籤/搜索