Parse cloud code

Preview:

DESCRIPTION

 

Citation preview

Parse Cloud CodeBuilding Web Apps WITH Programming Server a little bit.

http://goo.gl/oW1cZD

2014 Spring Web Programming, NCCUAuthor: pa4373 (Licensed by CC-By 4.0)

Parse is great convenient platform for developing apps.

Basic Operation

Create,Read, Update, Delete, (CRUD)

What if we want more?

To work with Cloud Code, you shall understand how Parse actually works.

RESTful API

● RESTful API is the design principle of Web Service

● Web Service: content consumable for computer program. (Developers love it!)

RESTful API

How web service client works:1. Construct HTTP request2. Get HTTP response3. Parse HTTP response (plain text) into native

data types supported by your programming language.

4. Do whatever you like.

Programming language independent.

RESTful API{ "resultCount":1, "results": [{"wrapperType":"artist", "artistType":"Artist", "artistName":"Jack Johnson", "artistLinkUrl":"https://itunes.apple.com/us/artist/jack-johnson/id909253?uo=4", "artistId":909253, "amgArtistId":468749, "primaryGenreName":"Rock", "primaryGenreId":21, "radioStationUrl":"https://itunes.apple.com/station/idra.909253"}]}

var object = JSON.parse(res);// Do something with object variable.

plain text

RESTful API

Q: How client & server talks to each other?● protocol, standard

○ SOAP (Simple Object Access Protocol)○ XML RPC ○ REST

RESTful API: SOAP

RESTful API: XML RPC

HTTP/1.1 200 OKDate: Sat, 06 Oct 2001 23:20:04 GMTServer: Apache.1.3.12 (Unix)Connection: closeContent-Type: text/xmlContent-Length: 124

<?xml version="1.0"?><methodResponse> <params> <param> <value><double>18.24668429131</double></value> </param> </params></methodResponse>

POST /xmlrpc HTTP 1.0User-Agent: myXMLRPCClient/1.0Host: 192.168.124.2Content-Type: text/xmlContent-Length: 169<?xml version="1.0"?><methodCall> <methodName>circleArea</methodName> <params> <param> <value><double>2.41</double></value> </param> </params></methodCall>

RESTful API: REST

REST: Representational State Transfer

What is that?The story begins with the invention of HTTP by Sir Tim-Berners Lee.CERN, Swiss, 1990

RESTful API: REST

● WEB is a place providing resources.● the very first version of HTTP:

○ GET● HTTP 1.0

○ GET, POST and HEAD● HTTP 1.1

○ GET, POST, HEAD, OPTIONS, PUT, DELETE, PATCH

RESTful API: Resources

A resource is an object with a type, associated data, relationships to other resources,

http://restful-api-design.readthedocs.org/en/latest/scope.html

RESTful API

How Parse WorksYour Code

Parse SDK (黑箱)

產生HTTP請求 產生HTTP回應

Parse Cloud (RESTful API)

Cloud Code

Bring server programming back to Parse while not entirely dealing with server logic, Awesome!

docs: https://parse.com/docs/cloud_code_guide

Cloud Code

All source code available on GitHub:

$ git clone https://github.com/pa4373/wp2014s_cloudcode_example.git

Use Cloud Code

Install command-line tool:● OS X / Linux

○○ python, curl is required. ( usually included in OS. )

● Windows○ https://parse.com/downloads/windows/console/parse.zip

$ curl -s https://www.parse.com/downloads/cloud_code/installer.sh | sudo /bin/bash

Use Cloud Code

Setting up Cloud Code# Create new cloud code folder containing basic files $ parse new cloudcode_demoEmail: pa4373@gmail.comPassword: # You won’t see **** while typing, stop asking!1: ParseStore

2: PeerEvaluation

3: cloudcode_demo

Select an App: 3 # You shall see all apps on Parse, select one to link with$ cd cloudcode_demo # change into the folder newly created

Use Cloud Code

Q: What’s my password?A: If you use Facebook, Google, GitHub to login,you might need to go to “Account” to manually set your password.

Use Cloud Code

Basic folder structure# let’s see what parse cloud deploy created for us.

├── cloud│ └── main.js# This is where cloud code are stored.

├── config│ └── global.json# A JSON file telling Parse how to deploy your code,

# normally you don’t need to worry about it.

└── public└── index.html

# Few static files you want Parse to host.

Use Cloud Code

Write the very first cloud code function:Open main.js and add the following codes.

Parse.Cloud.define("hello", function(request, response) {

response.success("Hello world!");

// You need to include response.success/error in Cloud

Code indicating the end of the request, or the codes will

went wrong.

});

Use Cloud Code

Deploy to the cloud:in the project directory, typing:

$ parse deploy

Uploading source files

Finished uploading files

New release is named v2 (using Parse JavaScript SDK v1.

2.18)

Use Cloud Code

Call the function we just wrote. (Client JS)

Parse.Cloud.run('hello', {}, {

success: function(result) {

window.alert(result);

// result is 'Hello world!'

},

error: function(error) {

}

});

Use Cloud Code

Call the function we just wrote.

Use Cloud Code

Cloud Code Dashboard

Files: Cloud Code (Live editing)Logs: console.log (Great for debugging)Scheduled Jobs: See queued jobsJob Status: See job status

Use Cloud Code

Topic Covered Today:● beforeSave, afterSave, beforeDelete, and

afterDelete● Parse.Cloud.httpRequest● Background Jobs● Modules● Settings for Development vs. Production

Use Cloud Code

beforeSave, afterSave, beforeDelete, and afterDelete:Act as a hook, allow developers to perform some operations before CRUD.

Use Cloud Code

Change its value before the object is saved on Parse.

Parse.Cloud.beforeSave("ExampleClass", function(request,

response) {

request.object.set("text", "Always the same.");

response.success();

});

Use Cloud Code

Save an object to Parse and retrieve its value.(Client JS)

var ExampleClass = Parse.Object.extend("ExampleClass");

var example_object = new ExampleClass();

example_object.set('text', 'I don\'t believe it!');

example_object.save(null, {

success: function(object){

var text = object.get('text');

window.alert(text);

}, error: function(object){

}

});

Use Cloud Code

Save an object to Parse and retrieve its value

Use Cloud Code

Parse.Cloud.httpRequest:Sometimes you need to fetch contents from other websites / web services, this is where Parse.Cloud.httpRequest comes in handy.

Use Cloud Codehttps://itunes.apple.com/search?term=john+mayer

Parse.Cloud.httpRequest({

url: 'https://itunes.apple.com/search',

params: {

term: request.params.singer // request.params as the Query Object

},

success: function (httpResponse) {

var SongClass = Parse.Object.extend('SongClass');

var ResObj = JSON.parse(httpResponse.text);

var newlyCreatedObjList = ResObj.results.map(function (e) {

var object = new SongClass();

object.set('trackName', e['trackName']);

return object;

});

// Resolve multiple asynchronous save problem (When to send http response?)

Parse.Object.saveAll(newlyCreatedObjList, {

success: function (list) {

response.success(request.params.singer + " is awesome!");

},

error: {}

});

},

error: function (httpResponse) {

console.error('Request failed with response code ' + httpResponse.status);

}

});

Use Cloud Code

Let’s put it into our ‘Hello World’ cloud code app!

Parse.Cloud.define("get", function(request, response) {

// Put codes shown on the last page here.

});

Use Cloud Code

Call the function we just wrote. (Client JS)

Parse.Cloud.run('get', {singer: 'John Mayer'}, {

success: function(result) {

window.alert(result);

// result is 'John Mayer is awesome'

},

error: function(error) {

}

});

Use Cloud Code

Call the function we just wrote. (Client JS)

Use Cloud Code

Call the function we just wrote. (Client JS)

Use Cloud Code

Background Jobs:Suitable for scheduled, time-consuming jobs

Use Cloud Code

Background Jobs:Let’s say: we want to run the codes on previous example per hour, periodically.

Use Cloud Code

Background Jobs:Define the jobs

Parse.Cloud.job("iTunesAPI", function(request, status) {

// Put the codes in the previous example here.

});

Use Cloud Code

Background Jobs:Parse.Cloud.job("iTunesAPI", function(request, status) {

Parse.Cloud.httpRequest({

url: 'https://itunes.apple.com/search',

params: {

term: request.params.singer

},

success: function (httpResponse) {

var SongClass = Parse.Object.extend('SongClass');

var ResObj = JSON.parse(httpResponse.text);

var newlyCreatedObjList = ResObj.results.map(function(e){

var object = new SongClass();

object.set('trackName', e['trackName']);

return object;

});

Parse.Object.saveAll(newlyCreatedObjList, {

success: function(list){

status.success(request.params.singer+" is awesome!"); // status required for a function to

stop.

}, error: {}

});

},

error: function (httpResponse) {

console.error('Request failed with response code ' + httpResponse.status);

}

});

});

Use Cloud Code

Use Cloud Code

Double quote.

UTC Time

Use Cloud Code

Use Cloud Code

Use Cloud Code

Advanced: Write a web crawler using Background Jobs, httpRequest

Programmers love API and web service.The regular users don’t.

How to extract information from normal web page?

Use Cloud Code

find string?

Good Luck!

Use Cloud Code

What if let codes ‘inspect element?’....

Use Cloud Code

Remarks: (DOM Tree) It’s a tree! Awesome!

Use Cloud Code

Parse doesn’t support modules written in C / C++, exposed from JavaScript.

No magical package manager (i.e npm, to use). TAT

Grab native javascript modules to cloud folder and put var module = require('cloud/<module filename>'); in your code.

Use Cloud Code

Grab https://github.com/isaacs/sax-js/blob/master/lib/sax.js as sax.js in cloud folder.Grab https://github.com/SamDecrock/node-xmlreader/blob/master/xmlreader.js as xmlreader.js in cloud folder.Replace var sax = require("sax"); with var sax = require("cloud/sax.js");

var saxparser = sax.parser(true); with var saxparser = sax.parser(false);

in xmlreader.js

https://parse.com/questions/htmlxml-parser-with-xpath-on-cloud-code

Use Cloud Code

XPath: a way to describe element in a DOM tree,

ex: /html/body/div[3]/div/ul/li/div[2]/p[2]

a little bit like CSS selector

Using ‘inspect element’ to look up Xpath.

Use Cloud Code

http://www.ericclapton.com/tour

/html/body/div[2]/div/div[3]/div/div[3]/div/div/table/tbody/tr/td[2]/a

Use Cloud Code/html/body/div[2]/div/div[3]/div/div[3]/div/div/table/tbody/tr[2]/td[2]/a

Use Cloud CodeParse.Cloud.job("webpage_scraping", function(request, status) {

var xmlreader = require('cloud/xmlreader.js');

Parse.Cloud.httpRequest({

url: 'http://www.ericclapton.com/tour',

success: function (httpResponse) {

xmlreader.read(httpResponse.text, function(err, doc){

var arena = doc.HTML.BODY.DIV.at(1).DIV.at(0).DIV.at(2).DIV.at(0).DIV.at(2).

DIV.at(0).DIV.at(0).TABLE.at(0).TBODY.at(0).TR.at(1).TD.at(1).A.at(0).text();

///html/body/div[2]/div/div[3]/div/div[3]/div/div/table/tbody/tr[2]/td[2]/a

var ConcertArenaClass = Parse.Object.extend('ConcertArenaClass');

var obj = new ConcertArenaClass();

obj.set('arena', arena);

obj.save(null, {

success: function(obj){

status.success('arena saved.');

}, error: {}

});

});

},

error: function (httpResponse) {

console.error('Request failed with response code ' + httpResponse.status);

}

});

});

Use Cloud Code

var xmlreader = require('cloud/xmlreader.js');

xmlreader.read(httpResponse.text, function(err, doc){

var arena = doc.HTML.BODY.DIV.at(1).DIV.at(0).DIV.at(2).DIV.at(0).DIV.at(2).

DIV.at(0).DIV.at(0).TABLE.at(0).TBODY.at(0).TR.at(1).TD.at(1).A.at(0).text();

// XPath: /html/body/div[2]/div/div[3]/div/div[3]/div/div/table/tbody/tr[2]/td[2]/a

// Watch the index diffirence. (start from 0, start from 1 -> None)

});

Use Cloud Code

Limitation:

Not handler malformed HTML markup,for other usage: https://www.npmjs.org/package/xmlreader

Use Cloud Code

Technique: Hack AJAX pageSome web page content is powered by AJAX technique, use ‘Inspect Elemenet’

Use Cloud Code

Always try to find API before writing your own crawler!

Be practical.

Use Cloud Code

ModulesImagine you got the codes from your peer, with 10k+ LoC in there.

Are you ready to debug to die?

Or say, write every function by your own.

And you wishes you were dead.

Use Cloud Code

Modules● Write your own module● Cloud modules● Use Third-party modules (Painful!)

Use Cloud Code

Modules● Write your own module

var coolNames = ['Ralph', 'Skippy', 'Chip', 'Ned', 'Scooter'];

exports.isACoolName = function(name) {

return coolNames.indexOf(name) !== -1;

}

var name = require('cloud/name.js');

name.isACoolName('Fred'); // returns false

name.isACoolName('Skippy'); // returns true;

name.coolNames; // undefined.

cloud/name.js

cloud/main.js

There’s a global exports object.

Use Cloud Code

Modules● Write your own module● Cloud modules

○ https://www.parse.com/docs/cloud_modules_guide● Use Third-party modules

○ Put pure js modules in your cloud directory, and use

‘var mod = require('cloud/name.js');’

Use Cloud Code

Settings for Development vs. Production

You got a app running for production,but you also want to add some cool features, what to do now?

Modify Production on the fly, dangerous and stupid!

Use Cloud Code

Use Cloud Code

Settings for Development vs. Production

Production App

Development App

Your Cloud Code Project

Use Cloud Code

Settings for Development vs. ProductionLink other apps to your project

# Link existing project to other apps, accessible via alias ‘production’$ parse add productionEmail: pa4373@gmail.comPassword: # You won’t see **** while typing, stop asking!1: ParseStore

2: PeerEvaluation

3: cloudcode_demo

4: cloudcode_demo_production

Select an App: 4

Use Cloud Code

Settings for Development vs. ProductionDeveloping Cloud Code

# Deploy tool will monitor files change on fly and updated to Parse server (No more deploy again)$ parse develop <APP_NAME>E2013-03-19:20:17:01.423Z] beforeSave handler in release 'v1' ran for GameScore with the input: {"original": null, "update":{"score": 1337}} and failed validation with Each GamesScore must have a playerNameNew release is named v58I2013-03-19T20:17:10.343Z] Deployed v58 with triggers: GameScore: before_save

Use Cloud Code

Settings for Development vs. ProductionDeploy Code to Production

$ parse deploy productionNew release is named v2

Recommended