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'.
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