Open itsjoeconway opened 7 years ago
@joeconwaystk see https://github.com/matanlurey/dart_serialize_proposal
@joeconwaystk also see my comment here: https://github.com/matanlurey/dart_serialize_proposal/issues/8#issuecomment-329644856
I think this issue is covering 2 things:
Map<String, dynamic>
. This is something that has been discussed in a number of places and I think we still hope to be able to do something better around this, but it's not clear what that will look like. See for instance #31876
JSON over HTTP Proposal
Abstract
The purpose of this proposal is to define an API for a productive JSON deserialization in Dart client-side code. The proposed API is not specific to JSON; it could be extended to any form of dynamic data binding. JSON makes a good example. This solution is currently not implementable in Dart 1.x. This solution should include support for all compilation targets.
Consider the result of some HTTP request as a list of JSON objects:
A productive way of making this request and getting back this list of JSON objects as Dart objects might look like the following:
Where a
Response.body.asList()
is of typeList<T>
as inRequest<T>
.T
must extend some type that has behavior for deserialization behavior. De-serialization of a single object follows the same pattern, but accessed withasObject()
.Declaring the parameterized type for
Request
requires minimal effort. In a simple case, it declaresmanaged
properties and extendsCodable
:Other
Codable
subclasses can bemanaged
:Such that the following JSON is deserializable:
As an alternative syntax, all
managed
properties can be declared as so:The name of the key in the payload can be specified with metadata:
Motivation
Moving dynamic data into and out of an application is a necessary component of a Dart application. Constraints on meta-programming on most Dart compilation targets require manual or code generated solutions. Manual solutions are tedious and prone to error, while code generation requires deeper knowledge of the platform, extra tooling and therefore deters new users.
A built-in solution to JSON deserialization is an expected feature of any modern application programming language; so much so that Swift modified their compiler to support it. The value-add of a unified mechanism to productively model JSON data as Dart objects is significant. A new user can immediately see results with an existing API (or one they are able to build quickly), which will impact their long-term usage of Dart.
Proposal
The
managed
keyword is applied to properties and accessors of a type. These properties and accessors are available to the interface of the type, but storage is deferred to some other mechanism. The following is syntactically valid:The base class
Object
adds a new property,managedMembers
, which contains runtime-available metadata for allmanaged
declarations. For AOT targets, this information is created during compilation. This effectively moves code generation into a compiler pre-processing step.The invocation
t.i=
is not a simple property assignment, but is resolved to an invocation of:Likewise, the getter
t.i
is an invocation of:Because
T
does not currently implementsetValueForKey
orvalueForKey
, this implementation must be provided byT
or a base class.Codable
implements these two methods as little more than map access:Thus, access to
managed
properties is always dynamic. (This part is debatable, but it allows for a tiered approach where this functionality is available earlier and can be optimized later without an API change.)A
Codable
is instantiated with aCoder
. This would require that constructors be inherited; that Dart constructors are not inherited is surprising and requires workarounds for some design patterns.Codable
would define two constructors:A
Coder
is an abstract key-value container object. A simple implementation would wrap aMap
:(Important: this does not limit concrete
Coder
s from implementing key-lookup in other ways. Additionally, aCoder
should not copy data.)The
Request<T>
object from earlier deserializes data as such:This requires that parameterized types can be instantiated and that their constructors are known.
Summary of Proposed Changes
managed
language keyword.Object.managedMembers
.managed
properties.Codable
andCodableKey
.