Thursday, November 14, 2013

Dart is Launched - V1.0

And with this tweet... Dart v1.0 is launched.

Friday, October 18, 2013

Web Components in Action... Launched...

Not entirely Dart related... but my new book Web Components in Action is now available from Manning in Preview (MEAP) form.  It's aim is to lead you through developing your web components, primarily using Polymer (this is part of the reason things have been a little quite from me...)

Download the free chapter 1 and let me know what you think.   It's also Manning's deal of the day today, 18th October... use the code: dotd1018au when you follow this link to the book's site on manning.com.

Tuesday, August 13, 2013

Translating the Web-UI x-click-counter to Polymer.dart

This blog post shows how to take the Web UI sample "x-click-component" project created from Dart Editor wizard, and convert it into a Polymer.dart project.  Along the way, I'll highlight some of the differences between Web-UI and Polymer (and some of the similarities).

Dart's web components project, called Web-UI, is migrating over to the Polymer project's web component framework.

One of the key differences between the Dart's Web UI project and Polymer is that Polymer doesn't require a separate build step (or the /out/ folder), at least while you're developing (you'll still want a build step when you deploy, to combine all the external imports).

Note: This blog post was written using Dart 0.6.15 r25822 and Polymer 0.5.3.

Creating the project


Let's start by creating a new project in the editor.

Create a new Web Application (using the web_ui library) project
This creates you a web project structure containing a set of example files.  After a few seconds, pub has installed the various packages and build.dart has finished running, your folder structure probably looks something like this:
The starting web-ui folder structure

Removing Web UI and Build.dart

The first step (and I'm sure you'll do this with a smile on your face) is to stop build.dart running.  Right click it, and click the handy menu option "Don't run build.dart"

Next, open the pubspec.yaml file, and remove all the current dependencies (likely to be browser, js and web_ui).  Add a polymer dependency:

Changing the custom element to Polymer

In your project there will be two files that represent the existing Web UI x-click-counter custom element.  These are xclickcounter.html, which provides the layout, and xclickcounter.dart, which provides the script.  

The existing x-click-counter defines itself as a custom element, has a button that lets you click it to increment a data bound value.  It looks like the screenshot below:
Example screenshot of the x-click-counter component
We'll go through a couple of iterations to modify this to Polymer.  First, we'll just get the custom element to show up in the page, and then we'll come back and look at the interactivity and data binding.

Before modification, xclickcounter.html looks like this:

xclickcounter.html before modification:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>

<html>
  <body>
    <element name="x-click-counter" constructor="CounterComponent" extends="div">
      <template>
        <div>
          <button on-click="increment()">Click me</button><br />
          <span>(click count: {{count}})</span>
        </div>
      </template>
      <script type="application/dart" src="xclickcounter.dart"></script>
    </element>
  </body>
</html>

There are three key parts that you need to be aware of in the original Web UI element:

  • Line 5: The <element> tag
  • Line 8: Calling an increment() function
  • Line 9: Databinding a {{count}} value
Start by modifying this to be a polymer element.  Change the <element> tag on line 5 to be a <polymer-element> and update the closing </element> tag on line 13. A polymer element is a like a supercharged custom element, with functionality provided by the Polymer framework.  It automatically uses things like the Shadow DOM and allows for simple component registration.
Notice also that the name is changed from x-click-counter to my-clickcounter, (for the sake of simplicity, I'm not going to rename the filenames).  I've also removed the {{count}} binding for now. We'll add it back again, soon

xclickcounter.html after modification:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>

<html>
  <body>
    <polymer-element name="my-clickcounter">
      <template>
        <div>
          <button on-click="increment()">Click me</button><br />
          <span>(click count: )</span>
        </div>
      </template>
      <script type="application/dart" src="xclickcounter.dart"></script>
    </polymer-element>
  </body>
</html>

Important:  Web Component custom elements names need to contain a hyphen. The intention is that the first part before the hyphen is a vendor prefix (to differentiate between different clickcounter components, for example).  See this discussion on the polymer mailing lists.
Let's change the associated script in the xclickcounter.dart file.  This represents our element in code.  Before modification it looks like this:

xclickcounter.dart before modification:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import 'package:web_ui/web_ui.dart';

class CounterComponent extends WebComponent {
  @observable
  int count = 0;

  void increment() {
    count++;
  }
}
First, let's change line 1 to import the polymer libary:


import 'package:polymer/polymer.dart';


Then let's change line 3 - CounterComponent class to extend PolymerElement instead of WebComponent


class CounterComponent extends PolymerElement {

Finally, we need to provide a method of registering our my-clickcounter element with the browser. The JavaScript version of Polymer elements do this using a JavaScript call, but in Dart, we can use a @CustomTag('my-clickcounter') class annotation.  The full changed xclickcounter.dart file is shown below (note, we'll return to the commented out functionality in a few steps:

xclickcounter.dart after modification:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import 'package:polymer/polymer.dart';

@CustomTag("my-clickcounter")
class CounterComponent extends PolymerElement {
//  @observable
//  int count = 0;
//
//  void increment() {
//    count++;
//  }
}

Now that the layout and script for the custom element is changed to use Polymer, let's see how you actually use them in your application's main page.

Using the Custom Element in your page

Currently, our main page (called polymerclicker1.html), and our main script (called polymerclicker1.dart) use Web UI.  The Web UI version of the files look like this

polymerclicker1.dart before modification:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import 'dart:html';
import 'package:web_ui/web_ui.dart';

// initial value for click-counter
int startingCount = 5;

/**
 * Learn about the Web UI package by visiting
 * http://www.dartlang.org/articles/dart-web-components/.
 */
void main() {
  // Enable this to use Shadow DOM in the browser.
  //useShadowDom = true;
}

polymerclicker1.html before modification


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <title>Sample app</title>
    <link rel="stylesheet" href="polymerclicker1.css">
    
    <!-- import the click-counter -->
    <link rel="import" href="xclickcounter.html">
  </head>
  <body>
    <h1>Polymerclicker1</h1>
    
    <p>Hello world from Dart!</p>
    
    <div id="sample_container_id">
      <div is="x-click-counter" id="click_counter" count="{{startingCount}}"></div>
    </div>

    <script type="application/dart" src="polymerclicker1.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

It only takes a couple of simple modifications to change these to use Polymer.   To start with, you can remove everything from the .dart file apart from an empty main() function.  We'll add something back into this once we start data binding a little later.

polymerclicker1.dart after modification:

1
2
3
void main() {
  // no content here yet.
}

Next, lets modify the HTML file.  This introduces a new piece of functionality, in the form of boot.js, found in the Polymer package.  The comments from that file explain fairly succinctly (we'll see it in action in a moment).

This script dynamically prepares a set of files to run polymer.dart. It usesthe html_import polyfill to search for all imported files, then it inlines all <polymer-element> definitions on the top-level page (needed by registerPolymerElement), and it removes script tags that appear inside those tags. It finally rewrites the main entrypoint to call an initialization function on each of the declared <polymer-elements>.
To get this working, replace the existing JavaScript script import on Line 22:  packages/browser/dart.js with polymer's packages/polymer/boot.js.

Let's also modify the #click_counter div to be an actual my-clickcounter element, by changing line 18 so that...


<div is="x-click-counter" id="click_counter" count="{{startingCount}}"></div>
  <!-- becomes... -->
<my-clickcounter id="click_counter" count="{{startingCount}}">
                                                           </my-clickcounter>

Now, the polymerclicker1.html should look like this, with lines 18 and 22 changed.:

polymerclicker1.html after modification


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <title>Sample app</title>
    <link rel="stylesheet" href="polymerclicker1.css">
    
    <!-- import the click-counter -->
    <link rel="import" href="xclickcounter.html">
  </head>
  <body>
    <h1>Polymerclicker1</h1>
    
    <p>Hello world from Dart!</p>
    
    <div id="sample_container_id">
      <my-clickcounter id="click_counter" count="{{startingCount}}"></my-clickcounter>      
    </div>

    <script type="application/dart" src="polymerclicker1.dart"></script>
    <script src="packages/polymer/boot.js"></script>
  </body>
</html>

Running in Dartium

You can go ahead and run this in now Dartium.  It doesn't have any interactivity (it will throw an error when you click the button), but it's worked without the build step
Tip: you might need to delete the web/out/ subfolder created by the old build.dart if you're being automatically redirected.

Let's take a look under the covers and see what's happened.  The old build.dart used to examine the static HTML page and combine all the HTML Imports into a runnable set of files before the application was run.  The polymer boot.js does this, but at runtime by replacing the our applications main() function (currently empty in polymerclicker1.dart) with a higher level main function that imports all the web componetns, initializes polymer and finally calls our own main() function (identified as userMain.main).  If you inspect elements in Dartium, you'll see the new script looks something like this:


1
2
3
4
5
6
7
8
9
import "http://127.0.0.1:3030/web/xclickcounter.dart" as i0;
import "package:polymer/polymer.dart" as polymer;
import "http://127.0.0.1:3030/web/polymerclicker1.dart" as userMain;

main() {
  polymer.initPolymer([
      "http://127.0.0.1:3030/web/xclickcounter.dart"
      ], userMain.main);
}

This new main() function passes in a list of all the polymer elements discovered through HTML Imports, and a callback to the original userMain.main() function.

From comments like this in the boot.js,
//TODO: rephrase when we split build.dart in two: analysis vs deploy pieces.
console.warn('boot.js only works in Dartium. Run the build.dart  tool to compile a depolyable JavaScript version')
it seems that the intention is that this is only used for development.

Adding data binding to the custom element

At the moment we're using the custom element, but it has no interactivity or data binding.  Remember that {{count}} we removed?  Let's put it back.  Polymer.dart uses an ObservableMixin to add the ability to observe changes to a variable through the @observable annotation.  This annotation allows two way data binding between the count field in the class instance, and any {{ count }} declarations in the template.
Uncomment the previously commented out section (lines 6 through 11), and add the ObservableMixin to the class definition (line 5) in xclickcounter.dart.

xclickcounter.dart after modification with functionality and observable mixin


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import 'package:polymer/polymer.dart';

@CustomTag("my-clickcounter")
class CounterComponent extends PolymerElement 
                             with ObservableMixin {
  @observable
  int count = 0;

  void increment() {
    count++;
  }
}

Let's also put the {{count}} binding value back into the xclickcounter.html at line 9.  The on-click="increment()" function call on line 8 changes as well - removing the parentheses (this is inline with the JavaScript version of Polymer).

xclickcounter.html after modification with functionality and data binding.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>

<html>
  <body>
    <polymer-element name="my-clickcounter">
      <template>
        <div>
          <button on-click="increment">Click me</button><br />
          <span>(click count: {{ count }})</span>
        </div>
      </template>
      <script type="application/dart" src="xclickcounter.dart"></script>
    </polymer-element>
  </body>
</html>

Finally, run the same polymerclicker1.html application, and you'll see that you can now click the "Click Me" button to increment the count.


Binding initial data values

The last step we need to take is to databind an initial value.  The original Web UI click counter initialized the counter with a value of startingCount=5. I've not found a way to do this exactly yet (and it may be that this part of Polymer hasn't been ported over yet), but you can achieve it through template binding.

The first step is to publish a public attribute on the my-clickcounter polymer element.  You do this using the attributes="" attribute on the <polymer-element> definition, making public any properties in the underlying Dart class.  Change Line 5 of xclickcounter.html as shown below:

xclickcounter.html after modification with published count attribute


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>

<html>
  <body>
    <polymer-element name="my-clickcounter" attributes="count">
      <template>
        <div>
          <button on-click="increment">Click me</button><br />
          <span>(click count: {{ count }})</span>
        </div>
      </template>
      <script type="application/dart" src="xclickcounter.dart"></script>
    </polymer-element>
  </body>
</html>

Now that the count property is published, let's bind a value to it in our main polymerclicker1 page.  To do this, you need to wrap the my-clickcounter in a template binding and bind that template to a model object, accessible through the elements model property in Dart code.

The template wrapping looks like this, in the polymerclicker1.html file:

<template id="counter_template" bind>
  <my-clickcounter id="click_counter" count="{{}}"></my-clickcounter>
</template>

Template binding uses the {{}} notation to bind to the model's value (rather than a property of the model).
We also need to modify the previously empty polymerclicker1.dart file to set the template model's value to 5.

polymerclicker1.dart after modification, setting a template model value


1
2
3
4
5
import 'dart:html';

void main() {
  query("#counter_template").model = 5;
}

Now, when you run this with the changes, the counter starts with a value of 5, and increments in response to button clicks.

Summary

In this example, you saw how to import custom Polymer elements without requiring a build step by using the new boot.js file imported from the polymer package.  This dynamically imports the various elements at runtime, rather than requiring a static build.
You also saw some simple data binding within an element itself using the @observable annotation (unchanged from Web UI).
Finally, you saw how one way to bind data into a custom element by wrapping it in a template.

As ever, comments are welcome, especially if it's to correct something in this post.

References

Most of the documentation on Polymer currently exists on the www.Polymer-Project.org homepage, or in as comments in the various source code files in Dart's Web_UI's polymer branch.  For a more fully featured Polymer example, take a look at the TodoMVC project in the polymer branch (hint, start with index.html).

The Polymer-dev group and the Dart Web-UI group also provide a discussion forum and other information.

Get the Gist:

You can find the final versions of the files here:


Thursday, July 11, 2013

Polymer.dart (very alpha) released to unify web components projects

TLDR: Polymer.dart released.

Web Components and Model Driven Views are a set of specifications that are being developed at the W3C.  Google's Dart team have been busy building their implementation of web components and model driven views under the Web UI name, and have built a nice framework for creating web applications.

Dart's Web UI

Using Web UI, you can define custom elements, like the Dart Editor's sample "Click Counter"

    <element name="click-counter" 
                constructor="CounterComponent" extends="div">
      <template>
        <div>
          <button on-click="increment()">Click me</button><br />
          <span>(click count: {{count}})</span>
        </div>
      </template>
      <script type="application/dart">
        import 'package:web_ui/web_ui.dart';

        class CounterComponent extends WebComponent {
          @observable
          int count = 0;
        
          void increment() {
            count++;
          }
        }  
      </script>
    </element>


And then import them into your application like any other HTML tag:

<click-counter count="5"></click-counter>


Dart's Web UI tool takes this and runs it through a compiler that inserts the required code to make this work cross-browser, even where web component spec's haven't been implemented.  You can read much more about Web UI on the Dart website.

Polymer Project

Separately, a group of bright Googlers have been working on the polymer project, announced at Google I/O this year.  The polymer project provides the underlying platform.js, which provides polyfills to fill in the gaps where native browser implementations of the various web components spec's don't yet exist.  This also lets you use web component technology across multiple browsers.

On top of the platform.js lives the Polymer libraries.  Polymer provides syntactic sugar to the underlying web components frameworks, in the same way that jQuery or dart:html provides syntactic sugar to the DOM.  It's also worth a note that last month Mozilla's also decided to use the Platform.js polyfills for their X-Tag project (which has similar goals to Polymer).

A Polymer web component looks like this:

<element name="click-counter" attributes="count">
    <template>
        <button on-click="increment">Click Me</button><br />
        <span>click count: {{ count }}</span>
    </template>
    <script>
        Polymer.register(this,{
          count: 0,
          increment : function(e) {
            this.count++;
          }
        });
    </script>
</element>

And is imported into your HTML in the same way:

<click-counter count="5"></click-counter>

The difference with this is that it doesn't need the underlying compile step that you get with Dart's Web UI tool (because the polyfills are applied at runtime rather than build time.

How does this affect Dart?

In an announcement this morning on the Dart Web UI mailing list, John Messerly announced the publishing of polymer.dart to pub, along with a number of the polyfill packages, such as observe, mdv, and shadow_dom. John notes:
"Today we continue our mission by publishing the beginnings of polymer.dart, our port of the Polymer stack. ... The Dart team is collaborating with the Polymer team to ensure that polymer.dart elements and polyfills are fully compatible with Polymer."
The compatible with polymer is great - hopefully this means you'll be able to take your Web Components  from Polymer and use it with Dart, and vice-versa.  At the very least, you'll be able to use your knowledge in both places.

Polymer.dart is at a very early stage (as indeed are the web components spec's themselves). John says:
"This is only the beginning. Polymer and web components are evolving, and we’re going to keep bringing that to you. Some of the things we’ll be working on are:
  • declarative <polymer-element> and custom elements.
  • more new, up-to-date polyfill packages, like html_imports.
  • removing the mandatory compiler step for polymer.dart. Just edit, save & refresh!
  • bring the Polymer UI elements to Dart.
  • up to date documentation for all of this shiny new stuff."

The removal of the compiler step is a going to be a great leap forward - it seems (to me at least) that's where a number of people have problems, both when developing and deploying.

John also says that:
It's still very early for polymer.dart, but we welcome you to try out the new packages. We’ll be maintaining the web_ui package for a considerable time, but will eventually be sunsetting it in favor of Polymer.
You can check out the source code in the polymer branch of Web UI, and take a look at some of the examples in the example subfolder.  You'll see that not much has changed at the moment, but watch this space!

Thursday, June 27, 2013

RESTful CRUD APIs with AppEngine, Cloud Endpoints and Dart code generation.

Dart and Web UI is an ideal platform for writing single page web apps.  These are typically made up of static files (html, css, js/dart) that are served up and execute and render in the browser.  Once running, they make requests back to the server for data, treating the server as a datasource API.

The combination of REST and JSON provides a great way for a server to expose an API to browser applications, and Dart can easily access JSON web services.

I was looking for a way to serve my client-side Dart application, and find a way to add server-side persistence in a scalable and open way.  AppEngine immediately sprang to mind.

AppEngine doesn't support server-side Dart at the moment (guess: don't hold your breath until after Dart reaches v1.0), but:


  1. It does support Java, Python, Go and PHP.  
  2. You can generate a "Cloud Endpoints" from your Java classes to provide a RESTful JSON based CRUD API
  3. The generated cloud endpoint implements Google's discovery API, and you can use the Dart discovery API client generator to generate a Dart pub package strongly typed to your CRUD API (thanks to the great work by Gerwin Sturm and Adam Singer).
  4. You can use this generated Dart in the browser to seamlessly access the AppEngine API. 

And that's what this blog post is about.

I'm going to use Java, Eclipse and the Google Eclipse Plugin for the AppEngine bits, and you can definitely use Python to achieve the same thing (I'm not sure about cloud endpoint support for Go or PHP yet).

Creating an AppEngine cloud endpoint 

There are plenty of tutorials about how to create an AppEngine project in eclipse using the Google plugin, so I'm not going to repeat them here.  Just follow the "Web Application Project" Wizard and uncheck the "Use GWT" option.

Once you have a project, you can go ahead and create a class that you want to persist.  In this example, it's a Message class for a guestbook (in a retro Geocities way).  The snippet below shows the basic class without all the getters and setters.


// java
public class Message {
  private String id;
  private String name;
  private String messageText;

  public Message() { }

  // snip getters and setters
}

To make this message an AppEngine persistent object, we just need to add a couple of annotations, namely @Entity and @Id.  I'm going to create my own ID values, but you can autogenerate them if you prefer.

Our class now looks like this:

// java
@Entity
public class Message {
  @Id
  private String id;
  private String name;
  private String messageText;

  public Message() { }
 
  // snip getters and setters
}

This is all we need to get a persistent server-side object.  Now we use the code generator that comes with the Google Eclipse Plugin to create an appengine cloud endpoint.

  • Right click your class and select "Create Cloud Endpoint Class" (as shown in the screenshot below)
Generating a Cloud Endpoint
That will create a couple of files. One for the data persistence side (EMF.java), and the other that exposes CRUD operations for the Message class (MessageEndpoint.java)

That's all there is to it!

Lets start the local AppEngine and access our API.  Run the project as a "Web Application" and that will start the local AppEngine server.


Accessing the API

There are a number of APIs exposed by appengine, and they live under the _ah/api URL path.  First up is the Discovery API, accessible via:




This exposes a list of all the REST APIs that our server is exposing.  There is only one at present - the MessageEndpoint API.   Let's discover that by navigating to:

http://localhost:8888/_ah/api/discovery/v1/apis/messageendpoint/v1/rest (referenced by the "discoveryLink" field.  That returns a host of information about the message endpoint API:


This JSON contains all the information needed to code generate strongly typed code for accessing the API.  Key parts include our Message class definition:

    "Message" : {
      "id" : "Message",
      "type" : "object",
      "properties" : {
        "id" : {
          "type" : "string"
        },
        "messageText" : {
          "type" : "string"
        },
        "name" : {
          "type" : "string"
        }
      }

and CRUD operations you can perform on it, such as getMessage, by using a GET request to message/{id}

   "getMessage" : {
      "id" : "messageendpoint.getMessage",
      "path" : "message/{id}",
      "httpMethod" : "GET",
      "parameters" : {
        "id" : {
          "type" : "string",
          "required" : true,
          "location" : "path"
        }
      },
      "parameterOrder" : [ "id" ],
      "response" : {
        "$ref" : "Message"
      }
    }

The complete list of operations are:
  • getMessage => GET: /message/{id}
  • insertMessage => POST: message/
  • listMessage => GET: message/
  • removeMessage => DELETE: message/{id}
  • updateMessage => PUT: message

We can try that by using the command line CURL command to try POSTing some data to insert a message, and GET the list of messages:

The following curl command POSTs some JSON data to the URL provided (all one line)
curl --header "Content-Type:application/json" --data "{'id':'msg1','name':'Chris','messageText':'Awesome Guestbook'}" http://localhost:8888/_ah/api/messageendpoint/message
Output of CURL POST command
I've inserted a couple of messages, with IDs "msg1" and "msg2".  We can list these with a simple GET request:

GETting the list of messages

Now we're ready to hook AppEngine up with Dart.

Using the Dart Discovery API Client Generator

Google Developer Experts Adam Singer and Gerwin Sturm spent some time earlier in the year building a code generation tool to build Dart packages from Google APIs using the Google's discovery APIs.  We're going to use that now.  The next part of this blog assumes that you have dart and git on your path (accessible from the command line).

First, we need to get the generator code, so we'll clone it from github by running the following command:

git clone https://github.com/dart-gde/discovery_api_dart_client_generator.git
Now you can run the generate.dart, passing in the URL of the discovery API for the messageendpoint:

cd discovery_api_dart_client_generator  
dart bin\generate.dart -u 
http://localhost:8888/_ah/api/discovery/v1/apis/messageendpoint/v1/rest
This outputs a Dart pub package in the output/dart_messageendpoint_v1_api_client subfolder.  We can import that into a Dart project.

Using the generated pub package in a Dart project.

We need to jump through a couple of hoops now, as we need to host the client-side Dart files within the AppEngine server.  AppEngine serves files from the /war folder within the Java project, and you can get your Dart files in there in a number of ways, for example, exporting a folder via the Java classpath output, symlinking directly within the war folder, or adding a build step to pub deploy the files into the war folder.

For the sake of ease with this demo, though, I'm just going to go right ahead and create a new Dart web project right inside the /war folder.  Typically, you'd want to only include the output of pub deploy, though.


Now that we've got a Dart project, let's check that we can access it through appengine, via the url: http://localhost:8888/client/web/client.html - if you're checking that URL in chromium, it won't do much because we've not generated the dart2js code yet.

In the Dart editor, let's create a launch that uses the appengine server instead of the built in Dart server.  That way it will run in Dartium, connect to the debugger, but be served from appengine:


Now that we can launch our app from the Dart Editor, into Dartium, served from AppEngine, let's look at accessing our new API.

Edit the pubspec.yaml to add the generated pub package.  I'm using a path url (which hard codes this app to my machine).  In the real world, you'd be better using a git location, so that you can share development among your team.


name: client
description: A sample web application
dependencies:
  browser: any
  google_messageendpoint_v1_api:
    path: c:\work\dart\projects\discovery_api_dart_client_generator\output\dart_messageendpoint_v1_api_client

Run a pub install if it's not run already, and you should get the package installed:

Installed endpoint package
In the screenshot above, you can see that there are three libraries created: browser, client and console.  The client library is shared between browser and console (which expose the relevant dart:html or dart:io APIs and re-export client).  Because we're working in the browser, we'll need to import the browser package using the following line:


import 'package:google_messageendpoint_v1_api/messageendpoint_v1_api_browser.dart';

We can now reference our Message class.  Let's write some simple code to create a message, and then retrieve a list of message objects.  This is going to output (using print()) to the browser console.  We're not building a UI here (that is left for a later blog post).

First, we create an instance of the endpoint class and set the root URL.  Remember those 5 CRUD methods on the API from earlier?  We also get great autocomplete from that:



Let's try listing the messages, which performs the same GET that we used with the CURL command earlier:


import 'dart:html';
import 'package:google_messageendpoint_v1_api/messageendpoint_v1_api_browser.dart';

void main() {
  // create an instance of the endpoint
  Messageendpoint endpoint = new Messageendpoint();
  endpoint.rootUrl = "http://localhost:8888/"; // set the root URL
  
  endpoint.listMessage().then((CollectionResponse_Message messageCollection) {
    print(messageCollection.items); // GET : message/
    print(messageCollection.items[0].messageText); // "Awesome Guestbook" 
  });
}


Let's try adding a new message, saving it back to the server, and retrieving it by ID:


  // create a message
  var message = new Message.fromJson({});
  message.id = "msg3";
  message.messageText = "I am a message";
  message.name = "Chris";
  
  // save it back to the server
  endpoint.insertMessage(message).then((Message savedMessage) {    
    // message is saved.  Retrieve it by ID
    endpoint.getMessage("msg3").then((Message loadedMessage) {
      print(loadedMessage.messageText); // "I am a message "
    });
  });

Summary

For now, that's it.   In this blog post you've seen how to

  • create a persistent Java class on AppEngine, 
  • generate a cloud endpoint to expose the Java class CRUD as a RESTful API
  • use the discovery API to generate a Dart pub package strongly typed to the Java class
  • use the generated pub package to read and write to the API.

There's a lot more that you can do with the discovery API and the code generated Dart, including adding OAuth tokens to authenticate requests, or setting the quota user and IP to enforce per-user limits.

You can find a whole host of generated APIs for most of the public google services on github, but I think the most powerful feature is being able to generate APIs for your own appengine apps.

References & further reading

Thursday, June 20, 2013

Dart heads into beta phase

With the latest release, Dart is now in beta.  As a "toolable language", one of the big highlights is a much faster Dart analyzer, for both the Dart Editor and the command line SDK.  The Dart editor is now really usable, and with its many refactoring tools, it helps you to build complex applications, with type and typo checking as you go.

Other highlights include a dart2js tool that produces 3.7x smaller JavaScript output, improved VM performance, and a pub deploy tool to create a deployable version for your website.

Well done to all everyone involved!

Announcement: http://googledevelopers.blogspot.co.uk/2013/06/dart-faster-editor-and-more.html
Release notes: http://news.dartlang.org/2013/06/release-notes-for-darts-beta-release.html



Thursday, May 23, 2013

Win-win for developers and users: Dart @ Google I/O 2013

Win-win for developers and users: Dart @ Google I/O 2013

Google I/O 2013 is now over, and Dart had a pretty good showing, with three Dart talks and a codelab.
Performance was a big theme throughout Google I/O, especially with Chrome and Mobile in mind. Mobile apps running with a touch screen need to be more responsive than ever to create a good user experience (when you're physically touching a widget, you expect it to respond immediately to your touch), and there was lots of discussion about the target 60 fps refresh rate on mobile.

Win 1: Great performance for users.

Lars Bak and Kasper Lund's talk on VM Performance highlighted some of the problems that they face when designing a VM. They've designed VMs in the past (including Hotspot VM and Chrome's V8), and although V8 made great leaps initially (an initial benchmark in Firefox ran at "100" when V8 was being invented. Now, the same benchmark runs at around "~16,000"), the rate of improvement is slow. In order to get the next "leap" in performance, they need to address some of the problems with the actual language (JavaScript). An example given in their talk is that V8 optimizes based upon known executions of a block of code up to that point. If, however, that code changes (such as inserting a new property into the prototype), the optimizer has to back-out the optimizations until it's ready to optimize again. All this has an overhead.

By designing a language that is designed to make it easy to optimize a VM for, Dart's is already ahead of V8 in terms of performance (after only about 2 years of development, compared to 7 years of V8).
enter image description here
Image courtesy Stephen Shankland / cnet
There are (currently broken) instructions on the Dart wiki about building a VM on ARM, and it has to be thought that a long-term goal must be to get the Dart VM (integrated with chrome?) running on Android. This has twin benefits for users: better application performance, and longer battery life (as there is less work done).

By making use of advance chip technologies, such as SIMD (Single Instruction, Multiple Data) the Dart VM is able to leverage the maximum power available. A great demo of this was the 3d demo of monsters - only around 35 were visible with SIMD turned off in the VM (at 60fps), but when SIMD turned on, 60fps was maintained with ~120 monsters.
enter image description here
Image courtesy Stephen Shankland / cnet

Win 2: Great experience for developers.

I also spent some time on the Dart stand in the sandbox talking to web developers about Dart, and went to the Dart codelab. As a developer, it's awesome to be able to leverage Web Components combined with Dart's well known language features (libraries, functional, unsurprising and familiar classes, optional typing), all wrapped up with with great tools such as package management, IDE, Debugger and type checker. Developers that I was talking to at the Dart stand seemed suitably impressed with what Dart currently had to offer (especially as many hadn't looked at it since its initial release).
"It can't really be this easy?"
In the Codelab, which used Web Components to build a multi-file, offline document editor, the other developers sat around me had positive views, with one even saying "It can't really be this easy? - It almost feels like cheating." - Yes, Dart really is productive. Give the codelab a try and see for yourself.

That quote summed up the current state of Dart for me, when I go around doing talks on Dart, and showing Dart to fellow developers, they are often surprised to see the great developer story and productivity gains. When combined with the improved performance of apps with the Dart VM, they start to see how it can help to move web applications on to the next level.

On JavaScript future.

Because Dart also targets JavaScript, any advances made in JavaScript to allow better JavaScript optimizations will also benefit developers and users. Developers still get the same great Dart development story, and users will benefit from increased performance of their JavaScript version of the Dart app. Of course, browsers that contain the Dart VM will likely to continue to remain faster running native Dart than the equivalent JavaScript.

The Sessions from I/O

Images from cnet article "Dart will rescue browsers from JavaScript"