cyan-at / appengine-rest-server

Automatically exported from code.google.com/p/appengine-rest-server
Other
0 stars 0 forks source link

Nested results using reference property #69

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Is there any way to traverse nested datastore objects (using the reference 
property in a list)?

e.g.
<Order>
<key>ahBkZXZ-a2lla2VmZWVzdGVucgsLEgVPcmRlchgCDA</key>
<waiter>Sander</waiter>
<date>2012-11-15T22:24:43.026827</date>
<orders>
<item>ahBkZXZ-a2lla2VmZWVzdGVuchALEgpCYXNpY09yZGVyGAEM</item>
</orders>
</Order>

Could the item in the orders list be fetched in one rest query?

Original issue reported on code.google.com by vanschoo...@gmail.com on 15 Nov 2012 at 10:29

GoogleCodeExporter commented 9 years ago
There is not a way to do that currently.  it's not an unreasonable idea.  how 
would you suggest controlling the level of nesting, or which objects were 
included?

Original comment by jahlborn@gmail.com on 16 Nov 2012 at 1:12

GoogleCodeExporter commented 9 years ago
I had i similar requirement. I need to be able to have a nested list of objects 
of another type and this must be serialized as objects and not as keys.

I have attempted to solve this myself and came up with something.

I am now able to have an object with a nested list of db.Key objects and those 
objects will be "unpacked" when serialized. It does not deal with nesting 
levels.

I must say a hacked away a little bit and probably it must be done differently 
but for me it does what i need.

Maybe someone with better understanding of the code can improve it?

Below is the code part i changed.

class ListHandler(PropertyHandler):
    """PropertyHandler for lists property instances."""

    def write_xml_value(self, parent_el, prop_xml_name, model,
                        blob_info_format):
        """Returns a list element containing value elements for the property
      from the given model instance appended to the given parent element."""
        values = self.get_value(model)
        if(not values):
            return None
        list_el = append_child(parent_el, prop_xml_name)
        for value in values:
            self.append_list_el(list_el, value, blob_info_format)
        return

    def append_list_el(self, list_el, value, blob_info_format=None):
        # dereference nested references
        if isinstance(value, db.Key):
            doc = list_el.ownerDocument
            nested_model = db.get(value)
            model_class = nested_model.__class__.__name__
            model_handler = Dispatcher.model_handlers[model_class]
            model_el = doc.createElement(model_class)
            model_handler.write_xml_value(model_el, nested_model, blob_info_format, None)
            list_el.appendChild(model_el)
        else:
            append_child(list_el, ITEM_EL_NAME,
                self.sub_handler.value_to_string(value),
                self.sub_handler.property_type)

Original comment by muijsenb...@gmail.com on 31 Jan 2013 at 7:24

GoogleCodeExporter commented 9 years ago
It sort of works but the json is not yet correct:

"images": {
        "item": [
        {"Image": 
            {"index": 0}
        }, 
        {"Image": 
            {"index": 1}
        }
    ]
}

Original comment by muijsenb...@gmail.com on 31 Jan 2013 at 11:18

GoogleCodeExporter commented 9 years ago
As i mentioned in my previous comment, enabling this support may not be 
especially difficult, the bigger question is how to control _when_ keys are 
dereferenced.  if you have multiple models which reference other models, you 
could get an arbitrarily large output when dereferencing.  not to mention that 
you could get stuck in an infinite, recursive loop if you have cyclic 
references.

i can't say that i've seen this addressed in other RESTish APIs, thus i am 
looking for some suggestions.  possibilities off the top of my head:

- hard-code it to a specific depth for specific model properties (at model 
config time)
- add some metadata to input requests which indicates desired level of nesting 
per property

Note that this also somewhat ties into issue 30.

Original comment by jahlborn@gmail.com on 2 Feb 2013 at 4:31

GoogleCodeExporter commented 9 years ago
I would say the first option. It gives you more strict control over what data 
is dereferenced and when.

Original comment by muijsenb...@gmail.com on 4 Feb 2013 at 9:01