On Oct 3, 2012, at 10:16 AM, Matthias Wessendorf <matzew(a)apache.org> wrote:
Hello,
> But what do you do for entities that are properties of your child resources i.e.
http://hostname/customers/100/orders?
>
> I think it would be best to have another HttpRestAdapter with a new URL:
http://hostname/customers/100/orders.
For this example (customers and orders of a specific customer), I
_think_ you would model it with TWO pipes:
=== HARD CODED EXAMPLE ===
// base pipeline
Pipeline pipeline = new Pipeline("http://hostname/");
Pipe<Customer> customersPipe = pipeline.add("customers",
Customer[].class);
==> maps to 'http://hostname/customers/'
Pipe<Order> ordersOfCustomer100 = pipeline.add("customers/100/orders",
Order[].class);
==> maps to 'http://hostname/customers/100/orders'
This would not work because you would have a / in the name. You would want to set
"customers/100/orders" as the endpoint and give the pipe some name like
cust100Orders
So here, technically in the implementation detail you would actually
have two _different_ HttpRestAdapter objects, one in the
'customersPipe' pipe and one in 'ordersOfCustomer100'.
Greetings,
Matthias
>
>>
>>>
>>> It means, that if we want to get a single instance of a resource
>>> (i.e. Task#100) we have to create a new HttpRestProvider with a
>>> new URL.
>>>
>>> For delete(), OTOH we can execute it with a specific id, and the
>>> same goes for put() to perform an update of a child resource.
>>
>>
>> Correct, a put on /tasks does make no sense. A delete on /tasks would
>> (I guess in most cases) mean all items are deleted, which feels
>> wrong....
>>
> Sure, it's all relative to endpoint URL - to decide if it makes sense or not. But
if I understand correctly the resource URL in our design should always be pointing to a
resource type url (i.e.
http://hostname/customers), and never to
http://hostname/customers/100, or
http://hostname/customers/100/orders), and that is the
reason for current semantics of get(), delete(), post(), put() ?
>
>> So IMO these put/delete operations make more sense on URIs, like
>> /tasks/{id} (update / remove a single item).
>>
>>
>>
>>>
>>> So we have GET, and POST operations performed on a 'parent'
>>> resource, and DELETE, and PUT operations performed on child
>>> resources. This asymmetry is confusing to me ... non-intuitive.
>>
>> Hrm... I disagree, as indicated in my sentences on put/delete
>> above...
>>
>> I like Stefan's image on restful URIs:
>>
http://www.infoq.com/resource/articles/rest-introduction/en/resources/fig...
>>
>
> +1
> Actually I'd say this exactly describes the API and usage as I proposed it above
:)
> URL defines a resource, and GET, DELETE, POST, PUT operate on that exact resource
URL.
> In this scheme of things you never operate on a 'child' resource, as the
'child' resource is already expressed through a URL (i.e.
http://hostname/customers/100, or
http://hostname/customers/100/orders - a collection on a
child resource).
>
>> The above picture 'models' URIs for this UML diagram:
>>
http://www.infoq.com/resource/articles/rest-introduction/en/resources/fig...
>>
>
> Actually I understand this as two layers where figure1 layer API, uses figure2 layer
API.
> That's the business interface layer that delegates to HttpRestAdapter, the two
layer approach. In our case persistence view with operations like findById ...
>
>
>> (Taken from this article =>
>>
http://www.infoq.com/articles/rest-introduction)
>>
>> However the figure2.jpg shows as well, that there maybe cases where a
>> DELETE on /tasks (or '/customers/{id}/orders') and a POST on
>> /tasks/{id} (or '/orders/{id}') can make sense.
>>
>> => We need to cover that too...
>> If I recall correctly those two 'corner cases' are also not covered
>> by
>> the JavaScript library.
>>
>>
>>> - I wouldn't eat exceptions, and return null even in a not-yet-real
>>> exception handling :)
>>>
(
https://github.com/danielpassos/aerogear-android/blob/new-pipeline/src/ma...)
>>>
>>> Really, either don't catch it, or if you do catch it, rethrow it as
>>> is, or wrap into another - normally RuntimeException is perfectly
>>> fine, so you don't pollute your API with throws declarations.
>>
>>
>> +1 on this comment - but he added a TODO already ;)
>>
>
> That's why I wrote 'even in a not-yet-real exception handling' i.e.
don't _ever_ do it like that :)
>
>>
>>>
>>> - I would use IllegalArgumentException here:
>>>
https://github.com/danielpassos/aerogear-android/blob/new-pipeline/src/ma...
>>>
>>> It's more appropriate, as it's a standard pattern for this kind of
>>> use-case. By convention UnsupportedOperationException is used for
>>> empty methods where interface contract is not fully supported.
>>>
>>
>> +1
>>
>>
>>
>>> - We have to do something about this "getId"
>>>
(
https://github.com/danielpassos/aerogear-android/blob/new-pipeline/src/ma...)
>>>
>>> One idea is to have an annotation - @Id. But scanning for
>>> annotations needs to be done at init time or lazily on first use
>>> ...
>>> So maybe we could have an abstract base class with abstract method
>>> getId() that every data object has to extend, and implement. A
>>> simpler, and more robust solution actually, as compiler will
>>> enforce it so there is no way for not providing one, as could
>>> happen with forgotten or wrong placement of @Id annotation for
>>> example.
>>>
>>
>> I think the problem here is that not every object has an 'id', the
>> field could be name 'recordId' - In JavaScript this is configurable.
>> iOS has a TODO here...
>>
>
> That's interesting. Can you give some examples?
>
>
>>
>> -Matthias
>>
>>
>>
>>>
>>> That's about it for now ... :)
>>>
>>> - marko
>>>
>>>
>>> ----- Original Message -----
>>>>
>>>>
>>>> Hi guys
>>>>
>>>>
>>>> I did some changes in the android library based on iOS stuff, it's
>>>> closer to the pipeline adapter implementation. I would appreciate
>>>> feedback and review.
>>>>
>>>>
>>>>
https://github.com/aerogear/aerogear-android/pull/1
>>>>
https://github.com/aerogear/aerogear-android-todo/pull/1
>>>>
>>>>
>>>> Thanks,
>>>> Passos
>>>> _______________________________________________
>>>> aerogear-dev mailing list
>>>> aerogear-dev(a)lists.jboss.org
>>>>
https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>>
>>> _______________________________________________
>>> aerogear-dev mailing list
>>> aerogear-dev(a)lists.jboss.org
>>>
https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>
>>
>>
>> --
>> Matthias Wessendorf
>>
>> blog:
http://matthiaswessendorf.wordpress.com/
>> sessions:
http://www.slideshare.net/mwessendorf
>> twitter:
http://twitter.com/mwessendorf
>>
>> _______________________________________________
>> aerogear-dev mailing list
>> aerogear-dev(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>
> _______________________________________________
> aerogear-dev mailing list
> aerogear-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/aerogear-dev
--
Matthias Wessendorf
blog:
http://matthiaswessendorf.wordpress.com/
sessions:
http://www.slideshare.net/mwessendorf
twitter:
http://twitter.com/mwessendorf
_______________________________________________
aerogear-dev mailing list
aerogear-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/aerogear-dev