72
Parse Cloud Code Building Web Apps WITH Programming Server a little bit. http://goo.gl/oW1cZD 2014 Spring Web Programming, NCCU Author: pa4373 (Licensed by CC-By 4.0)

Parse cloud code

  • Upload
    -

  • View
    2.100

  • Download
    5

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Parse cloud code

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)

Page 2: Parse cloud code

Parse is great convenient platform for developing apps.

Page 3: Parse cloud code

Basic Operation

Create,Read, Update, Delete, (CRUD)

Page 4: Parse cloud code

What if we want more?

Page 5: Parse cloud code
Page 6: Parse cloud code

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

Page 7: Parse cloud code

RESTful API

● RESTful API is the design principle of Web Service

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

Page 8: Parse cloud code

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.

Page 9: Parse cloud code

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

Page 10: Parse cloud code

RESTful API

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

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

Page 11: Parse cloud code

RESTful API: SOAP

Page 12: Parse cloud code

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>

Page 13: Parse cloud code

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

Page 14: Parse cloud code

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

Page 15: Parse cloud code

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

Page 16: Parse cloud code

RESTful API

Page 17: Parse cloud code

How Parse WorksYour Code

Parse SDK (黑箱)

產生HTTP請求 產生HTTP回應

Parse Cloud (RESTful API)

Page 18: Parse cloud code

Cloud Code

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

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

Page 19: Parse cloud code

Cloud Code

All source code available on GitHub:

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

Page 20: Parse cloud code

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

Page 21: Parse cloud code

Use Cloud Code

Setting up Cloud Code# Create new cloud code folder containing basic files $ parse new cloudcode_demoEmail: [email protected]: # 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

Page 22: Parse cloud code

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.

Page 23: Parse cloud code

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.

Page 24: Parse cloud code

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.

});

Page 25: Parse cloud code

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)

Page 26: Parse cloud code

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) {

}

});

Page 27: Parse cloud code

Use Cloud Code

Call the function we just wrote.

Page 28: Parse cloud code

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

Page 29: Parse cloud code

Use Cloud Code

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

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

Page 30: Parse cloud code

Use Cloud Code

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

Page 31: Parse cloud code

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();

});

Page 32: Parse cloud code

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){

}

});

Page 33: Parse cloud code

Use Cloud Code

Save an object to Parse and retrieve its value

Page 34: Parse cloud code

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.

Page 36: Parse cloud code

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);

}

});

Page 37: Parse cloud code

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.

});

Page 38: Parse cloud code

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) {

}

});

Page 39: Parse cloud code

Use Cloud Code

Call the function we just wrote. (Client JS)

Page 40: Parse cloud code

Use Cloud Code

Call the function we just wrote. (Client JS)

Page 41: Parse cloud code

Use Cloud Code

Background Jobs:Suitable for scheduled, time-consuming jobs

Page 42: Parse cloud code

Use Cloud Code

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

Page 43: Parse cloud code

Use Cloud Code

Background Jobs:Define the jobs

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

// Put the codes in the previous example here.

});

Page 44: Parse cloud code

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);

}

});

});

Page 45: Parse cloud code

Use Cloud Code

Page 46: Parse cloud code

Use Cloud Code

Double quote.

UTC Time

Page 47: Parse cloud code

Use Cloud Code

Page 48: Parse cloud code

Use Cloud Code

Page 49: Parse 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?

Page 50: Parse cloud code

Use Cloud Code

find string?

Good Luck!

Page 51: Parse cloud code

Use Cloud Code

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

Page 52: Parse cloud code

Use Cloud Code

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

Page 53: Parse cloud code

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.

Page 54: Parse cloud 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

Page 55: Parse 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.

Page 56: Parse cloud code

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

Page 57: Parse cloud code

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

Page 58: Parse cloud code

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);

}

});

});

Page 59: Parse cloud code

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)

});

Page 60: Parse cloud code

Use Cloud Code

Limitation:

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

Page 61: Parse cloud code

Use Cloud Code

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

Page 62: Parse cloud code

Use Cloud Code

Always try to find API before writing your own crawler!

Be practical.

Page 63: Parse cloud code

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.

Page 64: Parse cloud code

Use Cloud Code

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

Page 65: Parse cloud code

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.

Page 66: Parse cloud code

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');’

Page 67: Parse cloud code

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!

Page 68: Parse cloud code

Use Cloud Code

Page 69: Parse cloud code

Use Cloud Code

Settings for Development vs. Production

Production App

Development App

Your Cloud Code Project

Page 70: Parse cloud code

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: [email protected]: # You won’t see **** while typing, stop asking!1: ParseStore

2: PeerEvaluation

3: cloudcode_demo

4: cloudcode_demo_production

Select an App: 4

Page 71: Parse cloud code

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

Page 72: Parse cloud code

Use Cloud Code

Settings for Development vs. ProductionDeploy Code to Production

$ parse deploy productionNew release is named v2