[aerogear-dev] New Android Pipeline

Matthias Wessendorf matzew at apache.org
Wed Oct 3 11:40:21 EDT 2012


On Wed, Oct 3, 2012 at 5:35 PM, Kris Borchers <kris at redhat.com> wrote:
>
> On Oct 3, 2012, at 10:16 AM, Matthias Wessendorf <matzew at 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


Well, I was not using the 'correct' API - I just focused on the URL,
not on the name

==> pipeline.add("someName", "customers/100/orders", Order[].class);

makes sense ?


-Matthias



>
>>
>> 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/figure2.jpg
>>>>
>>>
>>> +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/figure1.jpg
>>>>
>>>
>>> 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/main/java/org/aerogear/android/core/HttpRestProvider.java#L86)
>>>>>
>>>>> 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/main/java/org/aerogear/android/pipeline/AdapterFactory.java#L34
>>>>>
>>>>> 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/main/java/org/aerogear/android/pipeline/RestAdapter.java#L76)
>>>>>
>>>>> 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 at lists.jboss.org
>>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>>>>
>>>>> _______________________________________________
>>>>> aerogear-dev mailing list
>>>>> aerogear-dev at 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 at lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>>
>>> _______________________________________________
>>> aerogear-dev mailing list
>>> aerogear-dev at 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 at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>
>
> _______________________________________________
> aerogear-dev mailing list
> aerogear-dev at 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



More information about the aerogear-dev mailing list