Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
317,78 KB
Nội dung
ptg
Summary
Being able to communicate securely with an external server has some huge advantages.
You can write custom Web services and host large databases.The possibilities are nearly
limitless.
There are many options out there for hosting providers.We chose Google App Engine
mainly because it is free for sites with small amounts of traffic, and free is nice.Amazon
Web Service (AWS) is a competing “cloud-computing” service that behaves differently
from GAE.With GAE you’re forced to use their Web servers and database back end, write
your code in Python or Java, and upload it all to their servers.With AWS you can pick
and choose which of their services to use and in what language you write your code.
There’s also Microsoft’s Azure, not to mention traditional Web hosting companies
from which you can rent physical servers sitting in physical racks.There’s also that spare
174 Chapter 8 OAuth and Phoning Home
Figure 8.3 Example of Canvas surface link on a user’s Profile
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
computer you have sitting in your closet, but that probably can’t handle too many
concurrent users (see Chapter 13, Performance, Scaling, and Security, to learn how to
scale your app).
Before deciding on a service, it’s best to shop around and do some research. See
what’s easiest, and possibly cheapest, for your new app.Whatever you choose, use the
basic principles outlined in this chapter to safely communicate between MySpace and
your hosting service.
Note
Code listings and/or code examples for this chapter can be found on our Google Code
page under http://opensocialtictactoe.googlecode.com.
Summary 175
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
This page intentionally left blank
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
9
External Iframe Apps
This chapter is essentially an extension of the preceding one. In Chapter 8 we discussed
several elements of OAuth that are relevant to this chapter and to writing external
iframe apps on the MySpace platform. We recommend that if you skipped Chapter 8,
go back now and read the sections that describe OAuth.
Moving forward in this chapter, we’ll assume you’re familiar with OAuth and with
setting up and publishing Web services using Python on Google App Engine (GAE).
In this chapter we’ll take our existing on-site app and port it over to an external
iframe, or off-site, app. Be prepared, because there’s a pretty large paradigm shift from an
on-site JavaScript app to an off-site app.
With on-site apps, you supply some markup and possibly a few Web services, and the
MySpace platform takes care of the rest.Your markup is wrapped in some headers and
footers (mostly script tags that pull in the OpenSocial container) so it can be correctly
rendered. When a user accesses the page, the MySpace infrastructure takes care of the
actual rendering of the page.
When the app starts running, it has very little knowledge of the user; it really knows
only the IDs of both the Viewer and the Owner.That means that the app has to send
out requests for data when it loads—maybe it requires a friend list, or some details from
your servers.These asynchronous requests are sent out while the app idles, perhaps with
a loading message and one of those “spinner” graphics twirling away to give the illusion
of activity.When the requests come back, the app leaps into action, as it should now
have all the data it needs to fully load.
That’s the typical flow of an on-site app, but off-site apps have a very different
pattern. For an off-site app, MySpace simply renders an iframe onto the page with the
src attribute set to the URL of your choice. Since you control the contents of the
URL, you have full control over the app. But this control comes at a cost; you are now
responsible for the rendering of the app.
Off-site apps behave much more like traditional Web pages. A request comes in, then
it’s picked up by your Web server and passed off for processing to your scripting
language of choice, such as PHP,ASP.NET, or Python. The request is then processed.
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
Let’s say we send off a REST request to the MySpace API for a friend list and also
pull some data out of our local database. The friend list and the data are then pushed
down onto the page used as the iframe app. In this case, the app has all the data it needs
to fully load at render time. The trade-off here is that on-site apps render immediately,
then idle while waiting for data. Off-site apps, by contrast, do their waiting for data up
front and then completely load.
The other big difference is that with on on-site apps you really have only one page.
In our Tic-Tac-Toe app we hide and show various HTML elements to give the illusion
of multiple pages. Off-site apps can have multiple actual pages, so markup and JavaScript
code can be separated a little more cleanly.Well-known techniques like clicking a button
that posts back a form can be used.
As you can see, there are some pros and cons to using an off-site app.The biggest
reason for using one would be that you have an existing app somewhere on the Web
that you could wrap an iframe around and there you go—you now have an instant
MySpace app. So, let’s dig a little deeper into what it would take to accomplish that.
REST APIs
What exactly is a “REST API”? Well, REST stands for REpresentational State Transfer,
which isn’t overly helpful as an actual definition. It essentially comes down to how
resources are accessed. The underlying assumption with REST is that objects and
records exist in one place, their universal resource identifier (URI), on the Internet and
stay there.The address is used to state the “who” of the object we wish to work with.
This is coupled with an action verb (for example, GET or POST) in the request to state
the “what” of what we wish to do.
How a REST Web Service Is Addressed
A REST Web service is addressed via URIs. Say we have a REST Web service that
returns data on fruit.To get a list of all the fruit available, we might access a URI like
this with a GET request:
http://fakefruitsite.com/fruit
Let’s say that Web service returns a list of available fruit, and one of the fruits listed is
apple. We might make a call like this to get a list of the types of apples available:
http://fakefruitsite.com/fruit/apple
Specifically, we might want to know which local producers grow Granny Smith
apples:
http://fakefruitsite.com/fruit/apple/grannysmith/producers
And even more specifically, there’s an orchard down the street that we want data on.
Each producer would have a unique identifier; this one’s is 12345. We might access the
price list for that producer’s Granny Smiths via the following URI:
http://fakefruitsite.com/fruit/apple/grannysmith/producers/12345/pricelist
178 Chapter 9 External Iframe Apps
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
REST APIs 179
This is an example of a REST API; we access the actual data we want by addressing
the URI in a specific way and use a globally unique identifier (GUID) to drill down to
specific entities. MySpace’s APIs follow a similar pattern but replace fruit with MySpace
users, GUIDs with MySpace IDs, and price lists with friend lists.
If you are not used to using REST, this may seem a little strange and low-level, but
MySpace provides several SDKs to help you out.The beauty of having an SDK is that
just about all of this is abstracted away. You’ll see shortly how easy it is to make requests
to the MySpace APIs using an SDK.
Setting Up an External Iframe App
Now that we understand what the REST APIs are, let’s take a look at how to set up an
app on MySpace that will make use of them. Up until now, our Tic-Tac-Toe app has
used MySpace’s OpenSocial container to make requests to the API, has lived on
MySpace servers, and has been written entirely in JavaScript.
What if we had an app already written and running on a Web site and wanted to
make it a MySpace app? Would we have to completely rewrite the app in JavaScript?
And convert all of our server communication to makeRequest? That’s one possibility,
but another is to simply “iframe your app.”
What that means is that MySpace provides the ability to load in an external iframe
on the Canvas surface instead of loading in the usual MySpace-hosted iframe. Let’s
walk through what it might take to convert parts of our Tic-Tac-Toe app to an
iframe app.
First we’ll need to create a new app by following the instructions found in Chapter 1,
Your First MySpace App. Once it’s created, navigate to Edit App Source and click on the
Canvas Surface tab (it’s the default tab). Instead of selecting HTML/Javascript Source
from the radio buttons at the top, we’ll select External Iframe.
Then, inside the External IFrame URL field, enter the starting point for your app. In
our case, and as shown in Figure 9.1, it’s http://opensocial—tic-tac-toe.appspot.com/play.
When the Canvas surface for this app loads, it will load the page you entered into the
External Iframe URL field instead of loading a MySpace-hosted page. In addition, it will
append several parameters to the source of the iframe in order to pass values to your app.
An example of this would be the following:
http://opensocial—tic-tac-toe.appspot.com/play?
appid=131583&
country=us&
installState=1&
lang=en&
oauth_consumer_key=http%3A%2F%2Fwww.myspace.com%2F461572677&
oauth_nonce=633738729982017828&
oauth_signature=11LDA8y%2FTsE36vg%2BKXKfSxJrkok%3D&
oauth_signature_method=HMAC-SHA1&
oauth_timestamp=1238276198&
oauth_version=1.0&
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
opensocial_owner_id=183399670&
opensocial_surface=canvas&
opensocial_token=H1YEBkwWjVWJLEo7n%2FVFM%2FDl1uvHTAVVfubkLWHNF1a4k9h1D6PCyLaNzTkFJ
➥AOCaxGIlluygnH2d4tuLcfbQnxbgNMN2%2FnPqp2sCZDCXt0%3D&
opensocial_viewer_id=183399670&
perm=%5B%22UT%22%2C%22UF%22%2C%22RN%22%2C%22PB%22%2C%22SN%22%2C%22%22%2C%22BI%22%
➥5D&
ptoString=COMMENTS%2CBLOG%2CBULLETINS%2CPROFILE%2CSEND_MESSAGE%2CSHARE_APP%2C
➥ACTIVITY
As you can see, our base URL, http://opensocial—tic-tac-toe.appspot.com/play, has
several query string parameters appended to it. There are some session-specific values,
such as the language and country of the current user, the user ID, and whether the user
has the app installed.The app’s ID and OAuth parameters are also passed down.This
allows you to verify the request in the same way we verified a signed makeRequest in
Chapter 8, Oauth and Phoning Home; essentially the iframe URL becomes an authenti-
cated OAuth request. We’ll discuss the opensocial_token, perm, and ptoString
parameters later in the chapter when we discuss cross-domain communication and
sending messages.
When our initial page loads, we’ll be able to determine the user’s ID, use the
MySpace SDK to fetch any data we might need from the MySpace APIs, and push the
data onto the page when it renders. Let’s implement the Play and Invite tabs of our
current Tic-Tac-Toe app.The Play tab requires the user’s Profile data, and the Invite tab
requires the user’s friend list.
180 Chapter 9 External Iframe Apps
Figure 9.1 Screen shot of the external iframe URL setup process.
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
REST APIs 181
The Server Code
Let’s go back to our code from Chapter 8 and update our app.yaml again. For reference,
you can find the Chapter 8 code in this folder:
http://opensocialtictactoe.googlecode.com/svn/trunk/chapter8/opensocial—tic-tac-toe/.
application: opensocial—tic-tac-toe
version: 1
runtime: python
api_version: 1
handlers:
- url: /ws
script: ws/ws.py
- url: /play
script: play/play.py
- url: /invite
script: invite/invite.py
As you can see, we’re going to use two separate pages for the two tabs.The handlers
for each (play.py and invite.py) are very similar. Let’s take a look at invite.py in detail and
then take a quick look at play.py.
import os
import ckeynsecret
from django.utils import simplejson
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from myspace.myspaceapi import MySpace, MySpaceError
from oauthlib import oauth
from entities import WinLoss
class Invite(webapp.RequestHandler):
def get(
self
):
id =
self
.request.get(
‘opensocial_viewer_id’
)
appid =
self
.request.get(
‘appid’
)
opensocial_token =
self
.request.get(
‘opensocial_token’
)
error = False
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
182 Chapter 9 External Iframe Apps
try:
int(id)
int(appid)
except:
error = True
ms = MySpace(ckeynsecret.CONSUMER_KEY, ckeynsecret.CONSUMER_SECRET)
ms.token = oauth.OAuthToken(
‘’
,
‘’
)
try:
friends = ms.get_friends(id)
except MySpaceError, mse:
error = True
if error:
msg =
‘Oops, there was an error, try refreshing the page!’
self
.response.out.write(msg)
return
json = simplejson.dumps(friends)
if json is None:
json =
‘{}’
template_values = {
‘friends_obj’
: json,
‘appid’
: appid,
‘ownerId’
: id,
‘opensocial_token’
: opensocial_token
}
path = os.path.join(os.path.dirname(__file__),
‘invite.html’
)
self
.response.out.write(template.render(path, template_values))
application = webapp.WSGIApplication(
[(
‘/invite’
, Invite)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ ==
“__main__”
:
main()
import ckeynsecret includes our consumer key and secret from an external file,
and we import the official MySpace SDK using from myspace.myspaceapi import
MySpace, MySpaceError
. For the request handler itself, we define only a GET
handler. Just as in our Chapter 8 code, it starts by checking the incoming user ID and
app ID to make sure they’re integers.
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
To make use of the MySpace SDK (you can download it at
http://code.google.com/p/myspaceid-sdk/ and pick the language of your choice), we
need to instantiate a MySpace object. All of the API functionality will be done through
this object. To initialize the MySpace object, you need to always do the following two
things:
ms = MySpace(ckeynsecret.CONSUMER_KEY, ckeynsecret.CONSUMER_SECRET)
ms.token = oauth.OAuthToken('', '')
The first line creates the MySpace object given the consumer key and secret.The
second creates an OAuth token; the two parameters are always empty strings when
accessing the MySpace API with an OpenSocial app.
Fetching a friend list is as simple as this:
friends = ms.get_friends(id)
That’s all there is to it; the SDK should take care of the rest. Assuming no exception
was thrown, we now have the user’s friend list.The circumstances for throwing an
exception are mostly permission-related—the user might not have the app installed,
might be blocking the app, and so on.
We then get the friend list ready to be pushed down onto the page by using
simplejson.dumps(friends). We pass a total of four items down to the page: the
friend list, the app ID, the owner ID, and the OpenSocial token.
REST API List
Now that we’ve seen one of the APIs in action, let’s take a look at what other
functionality the SDKs support. Table 9.1 describes all of the endpoints supported
by the MySpace SDK as of this writing. Some of the data has been truncated for
readability, but these are mostly just long URLs. The most important part, the schema
of the data, is intact. MySpace also maintains documentation for the APIs (not the
SDKs themselves, just the bare endpoints) at http://wiki.developer.myspace.com/index.
php?title=MySpace_REST_Resources.
REST APIs 183
Table 9.1 Overview of Endpoints Supported by the MySpace SDK
Function name
get_albums
Description Fetches a list of albums
Parameters <integer>user_id—the ID of the user
Sample response {
"count": 1,
"albums":
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... at http://opensocialtictactoe.googlecode.com/svn/trunk/chapter8 /opensocial tic-tactoe/index.html This page has a series of buttons on it, each corresponding to an endpoint (there are some additional buttons that were used in Chapter 8) Clicking a button causes a Web service request to some Python code, which can be downloaded at http://opensocialtictactoe.googlecode.com/svn/trunk/chapter8 /opensocial ... manually.The Play page has a similar link pointing back to the Invite page: Play When a user clicks this link, we pass the three parameters ownerId, appid, and opensocial_ token to the receiving page.This is just one of many ways to maintain session state in your app Now... pull down every Profile field (opensocial. Person.Field in OpenSocial speak) that MySpace supports.These fields are mapped loosely to the MySpace API using the detailtype parameter.There are three levels of detail: basic, full, and extended Let’s take a look at exactly what that means in handy tabular format as shown in Table 9.2 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark... responseJSON, and the new list is redrawn Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark From the Library of Lee Bogdanoff 202 Chapter 9 External Iframe Apps Now that we’ve seen the client code, let’s take a look at how the Web service itself looks.The first thing to do, as always, is to update our app.yaml file: application: opensocial –tic-tac-toe version: 2 runtime: python... But our response is no longer mapped into an opensocial. ResponseItem object, so we’re left to return our own errors as we see fit TTT.Lists.callback = function(response){ var current_list = TTT.Lists.getCurrentList(); var retryRequest = function(){ current_list.retries––; window.setTimeout(fetchFriends, 250); }; Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark From the Library... saved into a JavaScript object: var viewer = {{ viewer_obj }}; And the link back to the Invite page is created: Invite The big difference comes when we want to access the Profile data In the Tic-TacToe app, we have a printPerson function that takes... only gender_div.innerHTML = viewer.fullprofile.gender; // The response of getKey is defined by OpenSocial and therefore // you can compare the result to some known value if(viewer.fullprofile.gender.toLowerCase() === "female"){ div.style.backgroundColor = "#fcf"; } Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark From the Library of Lee Bogdanoff 206 Chapter 9 External Iframe... are "v" for OpenSocial container version and "f" for feature Here we’re asking for version 0.7 and the "rpc" feature; RPC is just another name for IFPC So this allows us to make IFPC calls using the 0.7 container Why the 0.7 container and not something a little newer, you may ask? We’ll get to that a little later, but there’s a good reason for it Please purchase PDF Split-Merge on www.verypdf.com to... "userId": 183399670, "uri": ➥"http:\/\/api.myspace.com\/v1\/users\/183399670", "webUri": "http:\/\/www.myspace.com\/cdsrussell", "userType": "RegularUser"}, "totalcomments": "0", Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark From the Library of Lee Bogdanoff REST APIs Table 9.1 193 Continued "totalvotes": "0", "dateupdated": "1\/1\/2009 2:30:22 PM", "runtime": "0", "id": 55701156,... "http:\/\/www.myspace.com\/cdsrussell", "userType": "RegularUser"}, "totalcomments": "0", "totalvotes": "0", "dateupdated": "1\/1\/2009 2:30:22 PM", "runtime": "0", "id": 55701156, Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark From the Library of Lee Bogdanoff 194 Chapter 9 External Iframe Apps Table 9.1 Continued "videoUri": "http:\/\/uri_to_video" Function name } get_activities_atom . Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
opensocial_ owner_id=183399670&
opensocial_ surface=canvas&
opensocial_ token=H1YEBkwWjVWJLEo7n%2FVFM%2FDl1uvHTAVVfubkLWHNF1a4k9h1D6PCyLaNzTkFJ
➥AOCaxGIlluygnH2d4tuLcfbQnxbgNMN2%2FnPqp2sCZDCXt0%3D&
opensocial_ viewer_id=183399670&
perm=%5B%22UT%22%2C%22UF%22%2C%22RN%22%2C%22PB%22%2C%22SN%22%2C%22%22%2C%22BI%22%
➥5D&
ptoString=COMMENTS%2CBLOG%2CBULLETINS%2CPROFILE%2CSEND_MESSAGE%2CSHARE_APP%2C
➥ACTIVITY
As. under http://opensocialtictactoe.googlecode.com.
Summary 175
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove