Thursday, July 15, 2010

abstract resource definitions vs. LLIDL

so i've been noodling on LLIDL and LLSD for a couple years now, and i think i've figured something out. i like the concept of an "abstract resource definition" a lot more than i like an "interface description language." (if you have no idea what i'm talking about, you may want to read my previous blog post "VWRAP Essentials : an abstract type system? hunh?." advanced students can take a look at the internet draft: draft-ieft-vwrap-type-system-00.)

the background

the objective of the abstract type system is simple and well defined: it provides system independent type semantics for structured data developed by protocol designers. that is, it defines types that are common to popular implementation languages. and it does it in a way that developers know the details of the types. like whether integers are 32 or 64 bits and whether radix 10 is supported in floats and so forth. the LLSD abstract type system describes how a small set of fundamental types work so implementers know how their "concretized" implementations should behave. and this is a good thing.

the problem

but after having mulled LLIDL around, i'm starting to see some issues with it. the main problem i have with it is that the interface is hopelessly entangled with the resource it describes. that is, you can't define an abstract resource without defining a method of access. for example, the current spec describes a way to say something like this:
 &info = {
name : string,
status_uri : uri
enroll_uri : uri
login_uri : uri
}

%% site_info << &info
in this example, the &info named type describes a structure that includes a string and three URIs. but the only context you can use the &info named type in is when you use a HTTP GET to access it. i think this is wrong.

it's wrong because it links the declaration of the structure of a resource with the transport used to access it. i have no problem with accessing resources over HTTP(S), but i do have a problem with ONLY accessing them over HTTP(S).

i think there's sufficient interest in the VWRAP working group to support the concept of making resource definition and access orthogonal. i would personally want to be able to have the option of using XMPP and (S)RTP when characteristics of those protocols are advantageous. but i don't want to have to create a new data definition language every time i want to go access a resource over a new transport.

furthermore, there are still open questions regarding content negotiation over HTTP(S). suzy deffeyes, john hurliman and i have reached a rough consensus on how to handle content negotiation, but we need to put it in an internet draft so other people can comment on it and implement it without having to refer to random email archives and IRC logs.

a proposed solution

i propose we layer an abstract resource definition on top of the abstract type system. the abstract resource definition can then be used to describe a transfer syntax (aka serialization scheme) for resources. we can then describe how each transport (HTTP(S), XMPP, etc.) carries serialized resource data. we can then describe interaction semantics independent of resource definition.

the benefit of this is it makes it easier to create systems that are transport-neutral. some of the lessons we learned from Second Life™ and the Linden Lab Legacy Protocol are that there's a LOT of stuff that's not "real time" data. I suspect that moving forward, we'll discover there are a lot of interactions that are modeled with the request-response pattern. i am proposing a solution that would offer deployers and protocol designers the ability to describe a resource without describing the method in which it is accessed.

more details

this proposal describes five components: the abstract type system, the abstract resource definition, the transfer syntax, the abstract interaction definition and the transfer mapping.
abstract type system

as mentioned above, the abstract type system defines a core set of types and type behavior. types are intended to be "concretized" in programming languages like C, Java, Python, whatever. we create an "abstract" type system so we're free to define the type behavior we want while not being tied to type behavior of a particular implementation language. individual implementers are responsible for ensuring that type semantics are consistent with the spec.

for example, imagine you were developing an application using an embedded 8 bit microprocessor and there was a protocol flow that involved incrementing an integer. a client might send you a 32 bit integer, assuming you would increment it. you would be responsible for modeling the behavior of a 32 bit integer despite the fact your micro-controller probably only natively knows about 16 bit ints.

abstract resource definition

the abstract resource definition is sort of like the abstract type system for collections. we define a resource as being either an individual item (a boolean, integer, etc.) or we define it as being a map or an array. the abstract resource definition system allows protocol developers to define the "shape" of resources. but because they are dynamic, implementations must allow for the type of a resource to differ from it's definition and for elements in map to be added and removed.

for example, you may want to define the following resource to describe an user logged into a system:

  RESOURCE agent {
name string,
identifier uri,
current_location uri
}

the abstract resource definition is used to group named data elements together into a dynamic structure. these structures will later be used by the abstract interaction definition.

transfer syntax (aka serialization scheme)

these are basically the three serialization schemes defined in the type-system draft: XML, JSON and Binary. they define how structured data is serialized into an octet string in preparation for transmission across a network. for example, the resource defined above might be serialized like this:

  <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map PUBLIC
"+//IDN meadhbh.org//xxdsd 0.1//EN"
"http://home.meadhbh.org/xml/xxdsd/0.1/xxdsd.dtd">
<map>
<key>name</key>
<string>Meadhbh Oh</string>
<key>identifier</key>
<uri>http://world.secondlife.com/resident/6e7477a7-2de5-4660-bc83-4a47096a18f0</uri>
<key>current_location</key>
<uri>http://world.secondlife.com/place/65f385f0-691c-5755-9ef0-15f3bb05c8b7</uri>
</map>
abstract interaction definition

LLIDL currently defines access verb sets that are tied to HTTP verbs. if we want to be able to access resources using multiple transports, this is wrong. i propose we define an abstract interaction description "language" that is later mapped to a particular transport.

i propose we have five "abstract" verbs: CREATE, READ, UPDATE, DELETE and EVENT. the first four should be pretty straight forward. They're used to create resources, read and write them and then maybe delete them. the last verb, EVENT, is used to define a resource an entity may receive without requesting it. things like object updates, incoming message session requests, etc.

transport mapping

the transport mapping maps abstract verbs from the abstract interaction description language to concretized protocol flows in the transport. so, for instance, you may use this to say that CREATE abstract access methods map to a POST verb in HTTP or that an EVENT message is delivered via the HTTP event queue.


conclusion

i'm going to wrap as much of this as i can into an internet draft and create some example code. but i figured i would get this idea out there so people can comment on it. just lemme know what you think...

No comments:

Post a Comment