[aerogear-dev] New Android Pipeline
Marko Strukelj
mstrukel at redhat.com
Wed Oct 3 12:34:21 EDT 2012
> 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'
>
> So here, technically in the implementation detail you would actually
> have two _different_ HttpRestAdapter objects, one in the
> 'customersPipe' pipe and one in 'ordersOfCustomer100'.
>
The problem I see with this is that you have to register an instance-specific Pipe. Makes no sense to have to register it, as you only need it once. Keeping it around afterwards is really a memory leak.
> 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
>
More information about the aerogear-dev
mailing list