The Parse Reflection Framework

At the moment I am working on a project where we use Parse.com as our BaaS (Backend as a service). We’re developing a news app for our customer with an administration homepage to create news and administrate some settings.

Parse is a great platform which helps us developer to produce applications faster and more reliable. But there are some things, you’re used to if you host your own backend, which parse does not provide. One big thing that’s missing is that they do not cover their great analytics service by their API. So it is not possible to present the current reports to your customer in a customised dashboard.

To fill this gap I developed a small javascript module (proof of concept) which provides the ability to call an URL of parse with a current logged in user. This could be used to download the analytics CSV data by an ajax request. Or it could be used to call the “clear all rows of this class” method. Or it could be used to delete all classes during development in your build script.

So how does the module works?

It’s a very simple web-client which stores the cookie of the last request and resends it with every new request. You just have to initialise the module with a valid user and password and call a url of parse.com:

var parseReflection = require('cloud/lib/parse-reflection.js'); parseReflection.init("youremail", "yourpassword"); parseReflection.getParseData("https://www.parse.com/apps/yourapp/analytics_batch" + "?from=1415055600&to=1417734000&stride=day&endpoints%5B0%5D%5Bendpoint%5D=" + "api_request", function (response) { res.send("" + response.text); });

This would send back the analytics data of the api_requests formatted as CSV.

I called the module “parse-reflection” because it is like the reflection framework in C# which gives us the ability to go into the metalayer.

Till I create a github project for this you will find the code of the module here:

Parse-Reflection.js

</p> <p>//PUBLIC VARIABLES var _username; var _password;</p> <p>var COOKIEJAR = ""; var AUTHENTICITY_TOKEN = "";</p> <p>var CONTENT_TYPE = "application/x-www-form-urlencoded"; var PARSE_LOGIN_URL = "https://www.parse.com/user_session/new"; var PARSE_SESSION_URL = "https://parse.com/user_session"; function parseLogin(next) { Parse.Cloud.httpRequest({ method: "POST", headers: { 'Content-Type': CONTENT_TYPE, 'Cookie': COOKIEJAR }, url: PARSE_SESSION_URL, body: "utf8=%E2%9C%93&amp;authenticity_token=" + AUTHENTICITY_TOKEN + "&amp;user_session%5Bemail%5D=" + _username + "&amp;user_session%5Bpassword%5D=" + _password, success: function (httpResponse) { console.log("logged in without 302"); next(httpResponse); }, error: function (httpResponse) { COOKIEJAR += httpResponse.cookies.user_credentials.name + "=" + httpResponse.cookies.user_credentials.value + ";"; next(httpResponse); } }); }</p> <p>function reflectParse(parseUrl, next) { Parse.Cloud.httpRequest({ method: "GET", headers: { 'Cookie': COOKIEJAR }, url: parseUrl }).then(function (response) { next(response); }); }</p> <p>function getAuthenticityToken(next) { Parse.Cloud.httpRequest({ method: "GET", url: PARSE_LOGIN_URL }).then(function (response) { COOKIEJAR = createCookieString(response.cookies); AUTHENTICITY_TOKEN = readToken(response.text); next(); }); }</p> <p>function readToken(html) { var res = "authenticity_token\" type=\"hidden\" value=\""; var authenticity_token = RemoveString(html, 0, html.indexOf(res) + res.length); authenticity_token = authenticity_token.substring(0, authenticity_token.indexOf("\"")); authenticity_token = encodeURIComponent(authenticity_token);</p> <p>return authenticity_token; }</p> <p>function RemoveString(str, startIndex, count) { return str.substr(0, startIndex) + str.substr(startIndex + count); }</p> <p>function createCookieString(cookies) { return cookies._parse_session.name + "=" + cookies._parse_session.value + ";"; }</p> <p>exports.init = function (username, password) { _username = encodeURIComponent(username); _password = encodeURIComponent(password); }</p> <p>exports.getParseData = function (parseUrl, next) { getAuthenticityToken(function () { parseLogin(function (loginResponse) { reflectParse(parseUrl, function (getResponse) { next(getResponse); }); }); }); }</p> <p>

I started to develop a small analytics library to provide functions which cover all analytics CSV exports to use them in your parse-project. Feel free to contribute your ideas and opinions to this!

This module is just a proof of concept! Do not use it in a real project! There is no warranty that it works!

Comments are now closed for this article