mdsol / hale

HALe specification draft
9 stars 3 forks source link

Allow specifying arrays of objects for link data #7

Open fosdev opened 10 years ago

fosdev commented 10 years ago

@ejennings-mdsol Mentioned the issue of a batch create that sent an array of some type of object. I think we could recursively add using data elements but we may need to include some flag like accept or require multiple or something.

brutski commented 10 years ago

@fosrias @sheavalentine-mdsol @miwest929 So, I suggest we add attribute to form, like 'accept: collection' meaning we will pass a collection of objects, so we end up having:

  create:
    doc: Creates a DRD.
    rt: drds
    links:
      self: DRDs#create
      help: Forms/create
    href: update
    accept: collection
    semantics:
      - href: name
        ext: validated_input_field
      - href: leviathan_uuid
        field_type: text
      - href: leviathan_health_points
        field_type: number
        validators:
          - required
          - min: 0
          - max: 100
        sample: 42
      - href: leviathan_email
        field_type: email
        validators:
          - required
          - pattern: "^.+@.+$"

How do we specify this in HALE is open question.

brutski commented 10 years ago

@fosrias @sheavalentine-mdsol @miwest929 @ejennings-mdsol

Here is a solution:

semantics:
  apartment_number:
    doc: Apartment number
    href: http://alps.io/schema.org/Text
  street:
    doc: Street name
    href: http://alps.io/schema.org/Text
  city:
    doc: City name
    href: http://alps.io/schema.org/Text 
  address:
    doc: Address
    href: http://alps.io/schema.org/Object? #should point to objects profile
    semantics:
      - href: apartment_number
        field_type: text
      - href: street
        field_type: text
      - href: city
        field_type: text

idempotent:
  update:
    doc: Updates persons address
    rt: none
    semantics:
      - href: address
        field_type: object
        multiple: true #implement support for this in API doc

And here is hale document for this case:

{
    "update": {
        "href": "http: //localhost:3000/person",
        "templated": true,
        "method": "PUT",
        "data": {
            "address": {
                "type": "object",
                "multi": true,
                "data": {
                    "apartment_number": {
                        "type": "text: text"
                    },
                    "street": {
                        "type": "text: text"
                    },
                    "city": {
                        "type": "text: text"
                    }
                }
            }
        }
    }
}
brutski commented 10 years ago

@fosrias @sheavalentine-mdsol @miwest929 @ejennings-mdsol To make it work we need to fix our serializers.

fosrias commented 10 years ago

Seems you could skip the "Address" semantics and do:

 semantics:
      address:
        doc: Some Addresses
        multiple: true #implement support for this in API doc
        data:
           - href: apartment_number
           - href: street
           - href: city

Or at least be able to do that. As for the Hale spec, not sure if we need the "multi" key if you specify type as an array as @sheavalentine-mdsol did in a prior example that we merged. Further, instead of using multiple, we could use "cardinality" and in Hale use that as well with a default to single, but if it is multiple, n or a fixed number could use that for both the descriptor document and hale. I will be working on getting what I suspect will be cardinality into ALPS soon hopefully. Does this address your questions @brutski?

brutski commented 10 years ago

@fosrias Yes, we don't need to introduce address semantic separately on a top-level. You can define it like you defined. However, you still need to have complex semantic elements in order to do artificial grouping of related items (aka fieldset in html). Yes, answers my question. Working on a solution in HALE.

sheavalentine-mdsol commented 10 years ago

Array won't serialize that way, you still need multi:

{
"address": {
                "type": "array",
                "multi": true,
                "data": {
                    "apartment_number": {
                        "type": "text: text"
                    },
                    "street": {
                        "type": "text: text"
                    },
                    "city": {
                        "type": "text: text"
                    }
                }
}

This will expect:

{ "address": 
  [ {
      "apartment_number": 1,
      "street": 123,
      "city": "New York"},
{
      "apartment_number": 2,
      "street": 123,
      "city": "New York"},
]
}

However this

"address": {
                "type": "object",
                "multi": true,
                "data": {
                    "apartment_number": {
                        "type": "text: text"
                    },
                    "street": {
                        "type": "text: text"
                    },
                    "city": {
                        "type": "text: text"
                    }
                }

Will Expect:

[ {
  "address": {
      "apartment_number": 1,
      "street": 123,
      "city": "New York"},},
{
  "address": {
      "apartment_number": 2,
      "street": 123,
      "city": "New York"},},
]
fosrias commented 10 years ago

Well both examples include multi. However, it seems the first example is what we want but without multi. What is expected with:

"address": { "type": "array",

            "data": {
                "apartment_number": {
                    "type": "text: text"
                },
                "street": {
                    "type": "text: text"
                },
                "city": {
                    "type": "text: text"
                }
            }

If there is no multi property and why? Seems we just need to define what type "array" means.

Am I missing something?

On Tue, Jul 22, 2014 at 7:49 AM, Shea Valentine notifications@github.com wrote:

Array won't serialize that way, you still need multi:

"address": { "type": "array",

            "multi": true,
            "data": {
                "apartment_number": {
                    "type": "text: text"
                },
                "street": {
                    "type": "text: text"
                },
                "city": {
                    "type": "text: text"
                }
            }

This will expect:

"address": { [ { "apartment_number": 1, "street": 123, "city": "New York"},{ "apartment_number": 2, "street": 123, "city": "New York"},]}

However this

"address": { "type": "object", "multi": true, "data": { "apartment_number": { "type": "text: text" }, "street": { "type": "text: text" }, "city": { "type": "text: text" } }

Will Expect:

[ { "address": { "apartment_number": 1, "street": 123, "city": "New York"},},{ "address": { "apartment_number": 2, "street": 123, "city": "New York"},},]

— Reply to this email directly or view it on GitHub https://github.com/mdsol/hale/issues/7#issuecomment-49749263.

brutski commented 10 years ago

So, @fosrias It looks like hale down below doesn't make sense.

"person" : {
  "type": "array",
  "data": {
     "name": {},
     "phone_number": {}
  }
}

What that means, essentially, is that you have something like: [ "Name", "1-234-567-8911" ] which is unrelated data.

However, this hale does make sense, which is an array of names.

"names": {
  "type": "array",
  "data": {
     "name": {}
  }
}

So were brainstorming this and and most of the use cases can be covered with "type: object" or "type: anything" and "multi: true". For example:

create:
  type: unsafe
  data:
    names:
      type: array
      data:
        - href: name

Which can be achieved with:

create:
  type: unsafe
  data:
    - href: name
      multi: true

Another example which doesn't make sense is, since data is unrelated and semantically different.

create:
  type: unsafe
  data:
    names:
      type: array
      data:
        - href: name
        - href: uuid

Example below on the other hand makes sense:

create:
  type: unsafe
  data:
    persons:
      type: array
      data:
        person:
          type: object
          data:
          - href: name
          - href: uuid

Which is exactly the same meaning like:

create:
  type: unsafe
  data:
    person:
      type: object
      multi: true
      data:
      - href: name
      - href: uuid

Thoughts?

brutski commented 10 years ago

@fosrias @sheavalentine-mdsol now, when I think about this, I really don't like keys like 'person', 'address' and etc. as grouping elements. We should probably introduce generic one, like in HTML, called 'fieldset'.

data:
  fieldset:
    type: object
    multi: true
    data:
      - href: name
      - href: uuid

HALE will look like:

"fieldset": {
  "type" : "object",
  "multi": true,
  "data": {
     "name": {...},
     "uuid": {...}
   } 
}

And it will expect:

[ 
  { "name": "Drd", "uuid": "1" },
  { "name": "Leviathan", "uuid": "2" } 
]

Thoughts?

fosrias commented 10 years ago

I don't think using fieldset under data is good because we now have a magic key "fieldset" vs an attribute of a data object. However, if we introduced a fieldset object vs. a data object I think that is an interesting thought. We were avoiding introducing another object into the spec but we could consider that.

@brutski I am not sure I followed your prior example with the wrong value for name etc. Maybe we could jump on a hangout sometime to talk about this with @sheavalentine-mdsol https://github.com/sheavalentine-mdsol if you want. Can do it impromptu. I am on skype everyday these days. Will send my name in separate email and you can ping me if you want to try and schedule something.

On Wed, Jul 23, 2014 at 4:58 PM, brutski notifications@github.com wrote:

@fosrias https://github.com/fosrias @sheavalentine-mdsol https://github.com/sheavalentine-mdsol now, when I think about this, I really don't like keys like 'person', 'address' and etc. as grouping elements. We should probably introduce generic one, like in HTML, called 'fieldset'.

data: fieldset:

type: object
multi: true
data:
  - href: name
  - href: uuid

HALE will look like:

"fieldset": {

"type" : "object", "multi": true, "data": {

 "name": {...},
 "uuid": {...}

} }

And it will expect:

[ { "name": "Drd", "uuid": "1" }, { "name": "Leviathan", "uuid": "2" } ]

Thoughts?

— Reply to this email directly or view it on GitHub https://github.com/mdsol/hale/issues/7#issuecomment-49952202.

sheavalentine-mdsol commented 10 years ago

Us this now addressed with the recursive ability of "data", if not, can we restate the problem?

fosrias commented 10 years ago

I think it is. But if we have not documented it clearly we should. @brutski can you comment?

brutski commented 10 years ago

@fosrias @sheavalentine-mdsol Yes, I think I did that here: Complex object. However, I have some doubts if we got this right. I may not fully understand the way data is serialized when doing POST for example. And the lack of understanding, may lead to my doubts. I'm more than willing to jump on the phone and discuss that.

sheavalentine-mdsol commented 10 years ago

If it's unclear, maybe we should create a new issue for "clear example of how to render POST data" and close this issue as resolved.