Saturday, August 31, 2013

The New JSON in Dart


I am not thrilled about this one.

At this point I have no less than 7 active Dart projects and libraries, most of which rely on the dart:json library to one degree or another. Unfortunately, dart:json is going away, replaced by similar functionality (but different APIs) in dart:convert. Since I want to continue to use my 7+ dart libraries and projects, I need to convert them… to dart:convert.

Actually, I think it makes sense to use the option #2 for most of the packages—at least in the first change. Option #2 is the Dart folks trying to make our lives a little easier in the transition. It breaks out a JSON package that supports the same API as the old dart:json library. This should make for fewer code changes, which I appreciate.

So I find all mentions of dart:json in Dart files that are contained in those 7 projects:
➜  repos  find \
    hipster-mvc \
    plummbur-kruk \
    ice-code-editor \
    dart-dirty \
    ctrl-alt-foo \
    dart-comics \
    csdart \
  -type f \
  -name '*.dart' \
  -exec grep dart:json {} \; \
  -print
import 'dart:json' as JSON;
hipster-mvc/test/test_server.dart
import 'dart:json' as JSON;
hipster-mvc/test/hipster_mvc_test.dart
import 'dart:json' as JSON;
hipster-mvc/lib/hipster_sync.dart
import 'dart:json' as JSON;
plummbur-kruk/test/browser_test.dart
import 'dart:json' as JSON;
...
There are a lot more of those.

The changes are pleasantly straight-forward. I have to include the json package as a dependency in each project's pubspec.yaml:
name: dirty
version: 0.1.0
description: Dart Dirty is a persistent, server-side HashMap - a dirt simple nosql DB.
author: Chris Strom 
homepage: https://github.com/eee-c/dart-dirty
dependencies:
  json: any
  unittest: any
Then, wherever the dart:html library was imported in each package's codebase, I replace it with the package equivalent:
library dirty;

import 'dart:io';
import 'dart:async';
import 'dart:collection';
import 'package:json/json.dart' as JSON;

// ...
Finally, I update my dependencies with pub update to get the json package:
➜  dart-dirty git:(master) ✗ pub update
Resolving dependencies............
Downloading json 0.6.9 from hosted...
Dependencies updated!
With that, I am ready to try things out. Thankfully, I have decent test coverage in most of my Dart code, so I can be reasonably confident that the json package is being exercised and is working as desired:
➜  dart-dirty git:(master) ✗ ./test/run.sh 
....
All 9 tests passed.

dartanalyzer lib/dirty.dart
Analyzing lib/dirty.dart...
No issues found.
Hooray for an easy upgrade path!

That approach works fine for each of my packages. I am curious about the dart:convert option, I so switch to that in Hipster MVC. I remove the newly added json package from the list of dependencies for that package:
name: hipster_mvc
version: 0.2.10
description: Dart-based MVC framework
homepage: https://github.com/eee-c/hipster-mvc
dependencies:
  browser: ">=0.6.19 <0.6.20"
  unittest: ">=0.6.19 <0.6.20"
  plummbur_kruk: ">=0.0.4 <0.0.5"
I then replace the import of the json package with dart:convert:
library hipster_sync;

import 'dart:html';
import 'dart:async';
import 'dart:convert';
//...
The only downside to dart:convert is that I have to replace the familiar JSON.stringify() and JSON.parse() with JSON.encode() and JSON.decode(). On the plus side, they are drop-in replacements:
  static parseJson(json) {
    if (json.isEmpty) return {};
    return JSON.decode(json);
  }
That works just fine. All of my tests pass and all of my code passes dartanalyzer analysis. Still, the decode/encode names combined with the newness of dart:convert lend an air of not-fully-baked to this change. I will leave it in place in Hipster MVC, but I am in no rush to make the change in my other packages. And I have the feeling that I will stick with the json package and its familiar stringify() and parse() functions in new code—at least until dart:convert has been around for a good long time.


Day #860

No comments:

Post a Comment