Scalable web applications
with Google Cloud Platform

Daniel Acton
May 18, 2013

Agenda

These slides: http://namekeepr.appspot.com/slides/

Scale - what is it and why do we care?

More:

  • Users
  • Devices
  • Screens
  • Browsers
  • Data

Less:

  • Complexity
  • Cost
  • Complexity
  • Code
  • Complexity

Google Cloud Platform

Namekeepr - an example app

Google App Engine

Google Cloud Endpoints

Google Cloud Endpoints - entity classes

Step 1: Create a POJO class and annotate it with JDO/JPA

@PersistenceCapable
public class SomeEntity { ... }
    

Step 2: Give it an some fields (one of which is a primary key)

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private String name;
    

Google Cloud Endpoints - endpoint classes

Step 1: Create a POJO class and annotate it

@Api(name = "myapi", version = "v1", description = "My API")
public class BusinessCardEndpoint {...}
    

Step 2: Create methods and annotate them

@ApiMethod(name = "list", path = "/list", httpMethod = HttpMethod.GET)
public CollectionResponse<BusinessCard> listBusinessCards(
  @Nullable @Named("cursor") String cursorString,
  @Nullable @Named("limit") Integer limit) 
  {...}
    

Each method returns a POJO which can be used by the caller (e.g. JSON on the web)

Google Cloud Endpoints - generate library

Datastore

DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Entity person = new Entity("Person");
person.setProperty("name", "Dan");
person.setProperty("hairColour", "brown");
ds.put(person);
    

Datastore

Filter filter =
  new FilterPredicate("hairColour",
                      FilterOperator.EQUAL,
                      "brown");
Query q = new Query("Person").setFilter(filter);
PreparedQuery pq = ds.prepare(q);
for (Entity result : pq.asIterable()) {
  // Do some stuff
}
    

Blobstore

BlobstoreService svc = BlobstoreServiceFactory.getBlobstoreService();
String postUrl = blobstoreService.createUploadUrl("/upload");
    
<form method="post" action="<%=postUrl%>">
    

Image Service

ImagesService imagesService = ImagesServiceFactory.getImagesService();

Image oldImage = ImagesServiceFactory.makeImage(oldImageData);
Transform resize = ImagesServiceFactory.makeResize(200, 300);

byte [] newImageData = 
  imagesService.applyTransform(resize, oldImage).getImageData();
    

HTML5

navigator.geolocation.getCurrentPosition(successFn, failureFn);
  
var c = document.getElementById('canvas');
var ctx = c.getContext('2d');
var img = document.getElementById('img');
ctx.drawImage(img, 0, 0);
  

HTML5

var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();

reader.onload = function(e) {
  // Do stuff, like show it on a canvas for preview
}

reader.readAsDataURL(file);
  

Media Queries

@media only screen and (max-width: 640px) { ... }
@media only screen and (min-width: 640px) { ... }
  

CSS Transforms

#myDiv {
  transition: color 0.5s;
  -moz-transition: color 0.5s;
  -webkit-transition: color 0.5s;
}

document.querySelector('#myDiv').style.color = 'red';
  

Google Closure

Closure Templates (a.k.a Soy Templates)

{template .helloWorld}
 Hello world!
{/template}

Closure Library: XmlHttpRequest

goog.require('goog.net.XhrIo');
    
var http1 = new goog.net.XhrIo();
http1.send('/uploadUrl', 'GET');
goog.events.listen(http1, 
  goog.net.EventType.COMPLETE, function(e) {
  // React to the HTTP response
  }
);
  

Google Closure

Closure Library: Templates

goog.require('goog.soy');
goog.soy.renderElement(element, helloWorld);
  

Closure Library: Namespacing

goog.provide('mylib.namespace');
  

Thank you!

Useful links