Getting REST with the Google App Engine & Android (Part 2) December 3, 2009 Cedric Hurst
Spantree Technology Group
[email protected]
Jason Shah
jsdf, LLC
[email protected]
David Parks
Developer-at-Large
[email protected]
Agenda • Intro & Theory
5 min
• Demo
5 min
• Server-side
10 min
• Client-side
10 min
• Open Q&A
remainder
2
Introduction • Cedric Hurst – Principal @ Spantree Technology Group, LLC – Co-Author of Exploring Java EE 5 (IBM Redbooks) – Focused on Enterprise Web Applications using Java, Java EE, Groovy, Grails & Dojo Toolkit
• Jason Shah – Principal @ jsdf, LLC – 10 years of strategy and technical consulting (Bain & Company, Trilogy) – Focused on mobile and web applications and services
• David Parks – Graduated M.S.C.I.S. June 2009 from Northwestern University – Focused on Drupal & Java development
Our project: Andraffle Situation
We want to track who attends Chicago GTUG events We want to give away prizes to those who attend
Complication
Attendees < Registrants Not everyone prints their confirmation ticket
Solution
Andraffle: an Android-based check-in and raffle system for events managed by eventbrite.com 4
Andraffle overview • Allow users to login to eventbrite.com from their Android phone • Allow the user to select from a list of events which they manage • Present the user with a list of people who have registered for their event (attendees) • Allow the user to “check-in” attendees when they arrive at the door, by scanning the barcode on their ticket or manually selecting from the list • Allow the user to view a list of randomly-selected, checked in attendees (to give away door prizes, raffles, assign secret santas, etc
What is a Service? • Functionality exposed through a standard interface – Service provider doesn’t care who the client is or how they use the data – Service consumer doesn’t care who the provider is or how they implement the service
What is a Web Service? • Functionality exposed through a standard interface on the Web – Service provider doesn’t care who the client is or how they use the data – Service consumer doesn’t care who the provider is or how they implement the service – Leverages the ubiquity of the Web to deliver services from providers to consumers
Typical Web vs. Web Services • The web typically marries presentation with data – Data usually embedded in HTML layouts – Makes it difficult for machines to separate useful information from formatting instructions
• Web services provide data specifically – Provided via some standard interchange format like XML or JSON – Much easier for machines to understand and interpret
The Web vs. Web Services (in the Real World)
Popular Approaches • POX (Plain Old XML) • SOAP (Simplified Object Access Protocol) • REST (REpresentational State Transfer)
REST in the Real World
Anatomy of a RESTful Request • Resource – Anything of interest that an application wants to expose on the web (the noun)
• URI – How resources are named and referenced
• Method – How resources are manipulated (the verb)
• Representation – Which format the resources are provided in (the language)
RESTful State Manipulation
Source: Manning, Restlet Green Paper
RESTlet Support
Agenda • Intro & Theory
5 min
• Demo
5 min
• Server-side
10 min
• Client-side
10 min
• Open Q&A
remainder
15
Login & Select Organizer
16
Select Event
17
Check in Users
18
Scan Barcode
19
Agenda • Intro & Theory
5 min
• Demo
5 min
• Server-side
10 min
• Client-side
10 min
• Open Q&A
remainder
20
The server-side challenge • Keep track of the checked-in state of an attendee • Select a random list checked-in attendees randomly • Communicate with the Android application to transfer information
21
To accomplish this, we need to… • Find a way to capture information about events and attendees on eventbrite.com • Decorate this information with a checkedin attendee state • Avoid exposing any information that is secured on eventbrite.com to unauthorized users
22
Initial theory: screen scrape • Pass the username and password from Android to our application server and login as the user in the app engine • We are now responsible for securing the username/password information on our server. Could be a nightmare if people reuse the same password on other sites • Our app engine code could break if eventbrite.com ever changes their layout
23
Better option: Use Eventbrite’s XMLRPC API
24
Example XML-RPC call
25
How do we authenticate?
26
Example XML-RPC call
27
XML-RPC API Challenges • We don’t want to pass the eventbrite.com login information to our app server • We can’t expect the user to know their API user key • Since the API is not RESTful, we can’t hook into their existing infrastructure through resource links
28
Solution • When the user logs in on Android, do some light screen-scraping on the phone to retrieve the user key • Pass the key into our RESTful API on the app engine and use that to authenticate with the Eventbrite XMLRPC • Transform the XML-RPC response to RESTful representations, decorated with the checked-in state, in the app engine
29
Agenda • Intro & Theory
5 min
• Demo
5 min
• Server-side
10 min
• Client-side
10 min
• Open Q&A
remainder
30
Andraffle application overview Authentication Activity*
Choose Organizer Activity
Display Attendees*
Event Resources Activity*
Andraffle** com.google.code.andraffle
Capture Activity*
DecodeThread CameraManager Intents ViewfinderView InterleavedYUV422LuminanceSource (and 6 others) com.google.zxing.client.android
* Accessess NetworkManager and other networking code ** Needs to be renamed
31
Andraffle application overview
* Accessess NetworkManager and other networking code ** Needs to be renamed
32
Authentication Challenge: Extract Data from HTML • In HTML, data and presentation are often mixed • Difficult for machines to understand informational content • Eventbrite provides certain authentication details only in HTML • We use Jtidy to clean and translate to XHTML • We use the Dom4J to navigate XHTML with an Xpath expression • This allows us to get the User Key and a list of Organizer IDs which we pass into the app engine 33
Using Dom4J and JTidy to tidy HTML
34
Using Xpath + dom4j to traverse document
35
Using Xpath + dom4j to select organizer info
36
Using XPath + dom4j to collect list of attendees
37
Agenda • Intro & Theory
5 min
• Demo
5 min
• Server-side
10 min
• Client-side
10 min
• Open Q&A
remainder
38
Appendix
39
Networking: Authentication Client
AppEngine Server
EventBrite
AuthenticationActivity Email address & password
HTTP response header with user cookie HTTP request header with user cookie
https://www.eventbrite .com/login
https://www.eventbrite .com/userKeyApi
HTML with user key (used as app engine password) HTTP request header with user cookie
https://www.eventbrite .com/userKeyApi
User ID & list of Organizers
40
Networking: Get events Client EventResources Activity
brite-rest.appspot.com (GAE)*
Secured HTTP request (orgId, userKey) HTTP request
NetworkManager
eventbrite.com **
GET /organizer/36748 9/events List of Events
HTTP response
GET /list_organizer_events? app_key=Qasyhidh37939 &user_key=1234567890 1&id=367489
EventResources Activity
AppEngine URLs have prefix http://brite-rest.appspot.com Eventbrite URLs have prefix https://www.eventbrite.com/xml/
41
Networking: Get attendees for event Client
DisplayAttendees
brite-rest.appspot.com *
eventbrite.com **
Secured HTTP request (org id, userKey) Event id: 3678490493
HTTP request
GET
NetworkManager List of attendees
/event/3678490493 / attendees HTTP response
GET /list_event_attendees? app_key=Qasyhidh379 39&user_key=123456 78901&id=367489049 3
DisplayAttendees
42 *AppEngine URLs have prefix “http://brite-rest.appspot.com”
Networking: Check in user Client Display Attendees
AppEngine Server*
EventBrite
Capture Activity HTTP request with changed check-in state as XML
PUT /event/ [eventId]/attendees/ [attendeeId]
NetworkManager
Success/failure
Display Attendees
Capture Activity
43 *AppEngine URLs have prefix “http://brite-rest.appspot.com”
Client retrieves events from Brite-rest
44
Brite-REST routes request to a secured resource identified and issues an authentication challenge
45
Brite-rest verifies with eventbrite that user_key associated with org_id
46
Brite-rest returns user events to client
47
Client requests list of attendees from Brite-REST
48
Brite-REST retrieves list of event attendees from eventbrite
49
Brite-REST updates its attendee info in its datastore
50
Brite-REST returns attendee list to Client
51
Client updates Brite-REST with checkedIn state change
52
Brite-REST returns modified state of attendee to Client
53