From d51e07620c9de883e550899bb5c705698013a674 Mon Sep 17 00:00:00 2001 From: Stephen Mizell Date: Sat, 29 Aug 2015 15:01:49 -0500 Subject: [PATCH 1/2] Add Embedded Refract serialization --- text/0000-embedded-refract.md | 361 ++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 text/0000-embedded-refract.md diff --git a/text/0000-embedded-refract.md b/text/0000-embedded-refract.md new file mode 100644 index 0000000..42797ca --- /dev/null +++ b/text/0000-embedded-refract.md @@ -0,0 +1,361 @@ +- Start Date: 2015-08-29 +- RFC PR: (leave this empty) +- Refract Issue: (leave this empty) + +# Summary + +This document outlines a new serialization format for embedding Refract. + +# Motivation + +1. Our current formats either look like XML, the DOM, or Lisp +1. People already "get" JSON +1. Other serializations we have are verbose + +# Detailed design + +## Overview + +For this serialization, there are two basic concepts: + +1. There is a reserved property name of `refract` +1. There is a Refract Object with properties: + - element + - meta + - attributes + - content + +All valid JSON that adheres to reserved property is valid Embedded Refract. + +## Basic JSON + +We'll start with a basic JSON example, which we'll say is a person and their bowling scores. + +```json +{ + "first_name": "John", + "last_name": "Doe", + "age": 28, + "scores": [150, 202, 145] +} +``` + +## Refracting Object Elements + +In Refract, this is an object with four members. With Embedded Refract, I can annotate by embedding refract using the `refract` property. + +```json +{ + "refract": { + "element": "object", + "meta": { + "id": "bowler-103" + } + }, + "first_name": "John", + "last_name": "Doe", + "age": 28, + "scores": [150, 202, 145] +} +``` + +This is what this would like in full Refract. + +```json +{ + "element": "object", + "meta": { + "id": "bowler-103" + }, + "content": [ + { + "element": "member", + "content": { + "key": { + "element": "string", + "content": "first_name" + }, + "value": { + "element": "string", + "content": "John" + } + } + }, + { + "element": "member", + "content": { + "key": { + "element": "string", + "content": "first_name" + }, + "value": { + "element": "string", + "content": "Doe" + } + } + }, + { + "element": "member", + "content": { + "key": { + "element": "string", + "content": "age" + }, + "value": { + "element": "number", + "content": 28 + } + } + }, + { + "element": "member", + "content": { + "key": { + "element": "string", + "content": "scores" + }, + "value": { + "element": "array", + "content": [ + { + "element": "number", + "content": 150 + }, + { + "element": "number", + "content": 202 + }, + { + "element": "number", + "content": 145 + } + ] + } + } + } + ] +} +``` + +## Refracting Value Elements + +If values do not have any meta values or attributes, there is no need to represent them as refracted. If I were to add some annotation to one of the values, it would show up as Refract and would be defined as Refracted by use of the `refract` property keyword. + +```json +{ + "first_name": "John", + "last_name": "Doe", + "age": { + "refract": { + "element": "number", + "meta": { + "id": "bowner-103-age" + }, + "content": 28 + } + }, + "scores": [150, 202, 145] +} +``` + +Above, I've added an ID to the age of the bowler. Notice how I just refracted that value in that specific place. This is also the same as: + +```json +{ + "refract": { + "element": "object", + "meta": { + "id": "bowler-103" + }, + "content": { + "age": { + "element": "number", + "meta": { + "id": "bowner-103-age" + }, + "content": 28 + } + } + }, + "first_name": "John", + "last_name": "Doe", + "scores": [150, 202, 145] +} +``` + +This will also support full member elements, so even this below is equivalent (note that it's a slight modification from the full Refract): + +```json +{ + "refract": { + "element": "object", + "meta": { + "id": "bowler-103" + }, + "content": [ + { + "element": "member", + "content": { + "key": "age", + "value": { + "refract": { + "element": "number", + "meta": { + "id": "bowner-103-age" + }, + "content": 28 + } + } + } + } + ] + }, + "first_name": "John", + "last_name": "Doe", + "scores": [150, 202, 145] +} +``` + +In full Refract, you would have to also provide the element for the key "age" in the previous example, but since we can rely on the `refract` keyword, we can leave it unrefracted. We could Refract it more later if necessary. + +## Refracting Array and Array Items + +Array items can be embedded without refracting the entire array. + +```json +{ + "first_name": "John", + "last_name": "Doe", + "age": 28, + "scores": [ + { + "refract": { + "element": "number", + "meta": { + "id": "bowler-103-game-1" + }, + "content": 150 + } + }, + 202, + 145] +} +``` + +Full arrays can also be refracted. + +```json +{ + "first_name": "John", + "last_name": "Doe", + "age": 28, + "scores": { + "refract": { + "element": "array", + "meta": { + "id": "bowler-103-scores" + }, + "content": [150, 202, 145] + } + } +} +``` + +## Refracting Attributes + +This makes it nice for refracting attributes, because now you know what attributes have been refracted. This could become: + +```json +{ + "refract": { + "element": "object", + "meta": { + "id": "bowler-103" + }, + "attributes": { + "foo": "baz" + } + }, + "first_name": "John", + "last_name": "Doe", + "age": 28, + "scores": [150, 202, 145] +} +``` + +```json +{ + "refract": { + "element": "object", + "meta": { + "id": "bowler-103" + }, + "attributes": { + "foo": { + "refract": { + "element": "string", + "content": "baz" + } + } + } + }, + "first_name": "John", + "last_name": "Doe", + "age": 28, + "scores": [150, 202, 145] +} +``` + +## Edge cases + +### Properties in Value Elements + +What would this mean, where we have the `foo` property? + +```json +{ + "first_name": "John", + "last_name": "Doe", + "age": { + "refract": { + "element": "number", + "content": 28 + }, + "foo": "bar" + }, + "scores": [150, 202, 145] +} +``` + +I would suggest it be treated as an attribute. This would be the same as: + +```json +{ + "first_name": "John", + "last_name": "Doe", + "age": { + "refract": { + "element": "number", + "attributes": { + "foo": "bar" + }, + "content": 28 + } + }, + "scores": [150, 202, 145] +} +``` + +Note: this scenario is different for objects, though, because those would be treated as actual properties. + +# Drawbacks + +"Don't we have more important things to do right now?" you may say. Sure! But it's the weekend and I'm doing some free-time thinking. + +# Alternatives + +We have alternatives already, so the idea would be that we don't do this if the current ones are enough. + +# Unresolved questions + +None at this point. From 8285692f901a311cbd484e768bcf0f1358655287 Mon Sep 17 00:00:00 2001 From: Stephen Mizell Date: Thu, 3 Sep 2015 17:28:05 -0500 Subject: [PATCH 2/2] Address comments --- text/0000-embedded-refract.md | 51 +++++++++++------------------------ 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/text/0000-embedded-refract.md b/text/0000-embedded-refract.md index 42797ca..d2a2245 100644 --- a/text/0000-embedded-refract.md +++ b/text/0000-embedded-refract.md @@ -18,7 +18,7 @@ This document outlines a new serialization format for embedding Refract. For this serialization, there are two basic concepts: -1. There is a reserved property name of `refract` +1. There is a reserved property name of `_refract` 1. There is a Refract Object with properties: - element - meta @@ -46,7 +46,7 @@ In Refract, this is an object with four members. With Embedded Refract, I can an ```json { - "refract": { + "_refract": { "element": "object", "meta": { "id": "bowler-103" @@ -146,10 +146,10 @@ If values do not have any meta values or attributes, there is no need to represe "first_name": "John", "last_name": "Doe", "age": { - "refract": { + "_refract": { "element": "number", "meta": { - "id": "bowner-103-age" + "id": "bowler-103-age" }, "content": 28 } @@ -162,7 +162,7 @@ Above, I've added an ID to the age of the bowler. Notice how I just refracted th ```json { - "refract": { + "_refract": { "element": "object", "meta": { "id": "bowler-103" @@ -171,7 +171,7 @@ Above, I've added an ID to the age of the bowler. Notice how I just refracted th "age": { "element": "number", "meta": { - "id": "bowner-103-age" + "id": "bowler-103-age" }, "content": 28 } @@ -187,7 +187,7 @@ This will also support full member elements, so even this below is equivalent (n ```json { - "refract": { + "_refract": { "element": "object", "meta": { "id": "bowler-103" @@ -198,10 +198,10 @@ This will also support full member elements, so even this below is equivalent (n "content": { "key": "age", "value": { - "refract": { + "_refract": { "element": "number", "meta": { - "id": "bowner-103-age" + "id": "bowler-103-age" }, "content": 28 } @@ -229,7 +229,7 @@ Array items can be embedded without refracting the entire array. "age": 28, "scores": [ { - "refract": { + "_refract": { "element": "number", "meta": { "id": "bowler-103-game-1" @@ -250,7 +250,7 @@ Full arrays can also be refracted. "last_name": "Doe", "age": 28, "scores": { - "refract": { + "_refract": { "element": "array", "meta": { "id": "bowler-103-scores" @@ -267,7 +267,7 @@ This makes it nice for refracting attributes, because now you know what attribut ```json { - "refract": { + "_refract": { "element": "object", "meta": { "id": "bowler-103" @@ -285,14 +285,14 @@ This makes it nice for refracting attributes, because now you know what attribut ```json { - "refract": { + "_refract": { "element": "object", "meta": { "id": "bowler-103" }, "attributes": { "foo": { - "refract": { + "_refract": { "element": "string", "content": "baz" } @@ -317,7 +317,7 @@ What would this mean, where we have the `foo` property? "first_name": "John", "last_name": "Doe", "age": { - "refract": { + "_refract": { "element": "number", "content": 28 }, @@ -327,26 +327,7 @@ What would this mean, where we have the `foo` property? } ``` -I would suggest it be treated as an attribute. This would be the same as: - -```json -{ - "first_name": "John", - "last_name": "Doe", - "age": { - "refract": { - "element": "number", - "attributes": { - "foo": "bar" - }, - "content": 28 - } - }, - "scores": [150, 202, 145] -} -``` - -Note: this scenario is different for objects, though, because those would be treated as actual properties. +We SHOULD ignore these properties. # Drawbacks