Upgrade to Pro — share decks privately, control downloads, hide ads and more …

REST APIs with JavaScript and Android

REST APIs with JavaScript and Android

An introduction to REST API design integrated with JavaScript and Android. Includes as much practical knowledge as we could fit into a 1-hour talk.

Nacho Coloma

June 28, 2012
Tweet

More Decks by Nacho Coloma

Other Decks in Technology

Transcript

  1. FUN FACT Did you read anything about SOA this week?

    Or the week before? Did you hear anything about SOA this year?
  2. A tale of two cities SOAP • Intended to sell

    books SOA • Marketing BS term • Not required to be SOAP! REST • Intended to do actual work API • Marketing BS term • Not required to be REST!
  3. I was recently talking with Jeff Barr, Amazon's chief web

    services evangelist. He let drop an interesting tidbit. Amazon has both SOAP and REST interfaces to their web services, and 85% of their usage is of the REST interface. Tim O'Reilly, 2003 http://www.oreillynet.com/pub/wlg/3005
  4. June 2012 Barack Obama directs all federal agencies to deploy

    a Web API within 12 months http://news.ycombinator.com/item?id=4056310
  5. (Java) code example @Path("/users") public class Users { @Inject private

    UsersService usersService; /** * HTML response */ @GET @Path("{key}") @Produces(MediaType.APPLICATION_JSON) public User view(@PathParam("key") int key) { User user = usersService.get(key); return user; } /** * JSON request/response */ @PUT @Path("{key}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public User put(User user) { return usersService.put(user); } }
  6. JSON is a simple format by design “My design criteria

    were three things: minimal, contextual, and a subset of JavaScript.” “When somebody proposed Hey we should do this crazy thing, we could be like – Nope” Douglas Crockford http://coding.smashingmagazine.com/2012/04/27/yahoos-doug-crockford-on-javascript/
  7. Dates with JSON Use the browser timezone? dateTime: 678678678678678 Which

    timezone is being applied here? dateTime: '20120628T18:00' Where in the world is this timezone? dateTime: '20120628T18:00+0200'
  8. Dates with JSON // manipulate the instant in time //

    e.g.: 'x seconds ago' dateTime: 678678678678678, // print the exact time in // referred time zone dateTimeStr: '20120628T18:00'
  9. Redundancy As with SOAP, do not aim at orthogonal data

    { “id”: 6, “creationDate”: 678678678678678, “creationDateStr”: “20120628T18:00”, “name”: “foobar”, “creator”: { “id”: 2, “name”: “Chuck Norris”, “avatar”: “http://goo.gl/inyourface.png” } }
  10. Collections curl GET /shows/5/performances { “data”: [{ “id”: 1, “name”:

    “foo” }, { “id”: 2, “name”: “bar” }], “cursor”: “ab45okli67fg” }
  11. Model • Model representation • Sync, validate, default values, modification

    events and more var Photo = Backbone.Model.extend({ defaults: { src: 'placeholder.jpg', title: 'an image placeholder' }, urlRoot: '/photos', initialize: function(){ this.on("change:src", function(){ console.log('Image source updated to ' + this.get("src")); }); } }); var somePhoto = new Photo({ src: "test.jpg", title:"testing"}); somePhoto.set({ src: "magic.jpg" }); somePhoto.save(); // POST request to /photos
  12. Views • View implementation • Render HTML, event handlers var

    PhotoSearch = Backbone.View.extend({ el: $('#results'), render: function( event ){ var tmpl = _.template( 'hello: <%= name %>' ); this.$el.html( tmpl(this.model.toJSON()) ); }, events: { "submit #searchForm": "search" }, search: function( event ){ //executed when the form '#searchForm' has been submitted } });
  13. Collections • Set of models • Sync, event propagation, underscore

    methods var PhotoCollection = Backbone.Collection.extend({ model: Photo, url: '/photos' }); var pc = new PhotoCollection(); pc.fetch(); pc.add([ {title: "My trip to Bali", src: "bali-trip.jpg"}, {title: "The flight home", src: "long-flight-oofta.jpg"}, {title: "Uploading pix", src: "too-many-pics.jpg"} ]); pc.save();
  14. Backbone fundamentals in-progress book by Addy Osmani about Backbone and

    REST https://github.com/addyosmani/backbone-fundamentals
  15. It's a world of trade-offs Shameless kidnapping of an awesome

    slide. Enjoy the original at https://speakerdeck.com/u/danwrong/p/putting-the-web-back-in-web-applications
  16. SoundCloud Continuous playback while the user is exploring (do not

    break the user experience). http://backstage.soundcloud.com/2012/06/building-the-next-soundcloud/
  17. Twitter Do not download a full application to see 140

    chars https://speakerdeck.com/u/danwrong/p/putting-the-web-back-in-web-applications
  18. JavaScript + REST APIs JS + REST More scalable Less

    costs: HW, bandwidth Faster navigation Server side Faster empty cache experience SEO Browser history URL routing Deep linking
  19. Rendering on the client • Get initial page • Get

    CSS • Get JavaScript • Get data • Render template
  20. Rendering on the server • Get initial page • Get

    CSS • Get JavaScript • Get data • Render template
  21. Market trend • March-May sales in Spain: • Android: 78.8

    % • RIM: 9% • Symbian: 6.2% • IOS: 3.3% Android Symbian RIM iOS http://www.kantarworldpanel.com/es/index.html#/Noticias/news-list/cuatro-de-cinco-smartphones-nuevos-son-android
  22. Examples { "id" : "7", "dateTimeStr" : "2013-02-08T22:00", "dateTime" :

    1360357200000, "venue" : { "id" : “5”, "name" : “Estadio Olímpico”, "address": "Cliburn, UK" }, "soldTickets" : 4, "totalTickets" : 100, "currency" : "EUR" } public class JsonPerformance { private String id; private String dateTimeStr; private long dateTime; private JsonVenue venue; private long soldTickets; private long totalTickets; private Currency currency; }
  23. Apache HttpClient HttpGet get = new HttpGet("http://localhost/foo/bar"); get.addHeader("Accept", "application/json"); DefaultHttpClient

    client = new DefaultHttpClient(); HttpResponse response = client.execute(get); String jsonStr = EntityUtils.getString( response.getEntity(), HTTP.UTF_8 );
  24. Spring for Android HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setAccept( Collections.singletonList(

    new MediaType("application","json") ) ); HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders); RestTemplate restTemplate = new RestTemplate(); restTemplate.setMessageConverters( Lists.newArrayList(new MappingJacksonHttpMessageConverter()) ); Performance performance = restTemplate.exchange( url, HttpMethod.GET, requestEntity, Performance.class).getBody();
  25. User Agent (1) // Set HTTP headers HttpUriRequest request =

    method.createRequest(uri); request.setHeader("User-Agent", getUserAgent()); private String getUserAgent() throws NameNotFoundException { return "Version/" + CONTEXT.getPackageManager().getPackageInfo( CONTEXT.getPackageName(), 0) .versionName + "(Linux; U; Android " + Build.VERSION.RELEASE + "; " + Locale.getDefault() + ";" + Build.MODEL + " " + Build.BRAND + "Build/" + VersionNameMapper.translate(Build.VERSION.SDK_INT) + ")"; } User Agent (1)
  26. User Agent (2) Mozilla/5.0 (Macintosh; U; PPC Mac OS X;

    en) AppleWebKit/125.2 (KHTML, like Gecko) Safari/125.8 Mozilla/5.0 (X11; U; Linux; i686; en-US; rv:1.6) Gecko Debian/1.6-7 Version/1.1(Linux; U; Android 2.3.6; es_ES;GT-N7000 samsungBuild/GINGERBREADu1)
  27. 3G/GPRS • Speed: Most connections are slow • Reliability: Depending

    on voice traffic load on base station • Availability: There are locations with no connection available
  28. This is not your mama's Facebook Single Sign-On • 100%

    Native • Available for iOS & Android
  29. WebView + Custom WebClient webview = (WebView) findViewById(R.id.webView); webview.setWebViewClient(new LoginWebClient());

    private class LoginWebClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { ... } @Override public void onPageFinished(WebView view, String url) { ... } @Override public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) { ... } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { ... } @Override public void onLoadResource(WebView view, String url) { ... } }
  30. Custom WebClient @Override public void onPageStarted(WebView view, String url, Bitmap

    favicon) { if (url.contains("/login/emailRequired") { webview.setVisibility(View.GONE); showErrorMessage(getString(R.string.must_be_registered)); return; } }
  31. NO

  32. NO

  33. Your REST API • Resource URLs • JavaScript application •

    Documented properly • Open source example of use • Demo page
  34. Your REST API • Resource URLs • JavaScript application •

    Documented • Open source example of use • Demo page
  35. Thanks! @nachocoloma + @jmanzanomorilla @extremasistemas Check it out: http://help.koliseo.com/api Keep

    reading: Jersey + REST: https://github.com/icoloma/simpleds-kickstart Backbone.js: https://github.com/addyosmani/backbone-fundamentals Android: http://developer.android.com/develop/index.html http://www.vogella.com/android.html