Unit tests
by Mark McLoughlin
Hey,
I've pushed out the beginnings of some junit tests
They uses RESTeasy's client API and the TJWS embeddable server, which
make things nice and simple
One interesting aspect of RESTeasy's client API is that we should be
able to use the server-side annotated interfaces on the client side too
e.g. you can do:
@Path("/")
public interface API {
@HEAD public Response head();
}
{
API api = ProxyFactory.create(API.class, uri)
Response response = api.head()
// Fetch link headers from response
}
but our use of '@Context UriInfo' in the server-side interfaces seem to
cause problems with this. That should be solvable somehow
But take a look at this - our server-side interface is:
@Path("/vms")
public interface VMs {
@GET List<VM> list();
@GET @Path("{id}") VM get(@PathParam("id") String id);
}
and I tried:
{
// get 'vms' uri from 'HEAD /'
VMs service = ProxyFactory.create(VMs.class, vms_uri)
List<VM> vms = api.list()
}
but this failed because it was doing a GET on '/vms/vms'
Which raises an interesting question - the server-side annotations
describe the URI structure, but we actually don't want clients to
hard-code the URI structure!
i.e. if we encouraged clients to use the the RESTeasy client API and the
server-side interfaces, that would kill our ability to ever modify the
URI structure
Cheers,
Mark.
14 years, 1 month
Some feedback on the REST docs and previous discussions
by Daniel Veillard
Hi all (hi Geert ;-)
I just joined the list and started reviewing the docs and the list
history, and I have a bit of feedback. Sorry for the lack of context
1/ I'm still reading 2/ I don't have the mail history loaded so can't
reply in the threads directly.
One think I noticed in the examples are the absolute lack of encoding
either at the HTTP header level and no XMLDecl:
------------------------------
GET /vms/ HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: {length}
<collection>
...
------------------------------
The XML parser handling the collection data has no indication about
encoding, and in that case the parser has to make an educated guess
(http://www.w3.org/TR/REC-xml/#sec-guessing), which will be assume UTF-8
(unless encoded un UTF-16 but nobody does that) and will crash and burn
if for some reason there is a non UTF-8 character in the stream. Note
that Apache by default tend to be completely screwed up and add
arbitrary encoding informations in the header, like
Content-Type: application/xml; charset:ISO-8859-1
if your software stack encoded the data in UTF-8 and one of the item
like a vm name is using non ascii chars, the parser will reject the
data.
Unfortunately adding an XMLDecl like
<?xml version="1.0" encoding="UTF-8"?>
<collection>
...
won't help, as the contextual information coming from HTTP header takes
over the own XML declaration informations (I fought that and lost, it's
broken sorry :-( ) so the best it to mandate that the encoding be
provided at the HTTP Content-Type: header (assuming the server won't
override it if present), and preferably UTF-8 to be sure anybody can
consume the data without betting thing wrong
Content-Type: application/xml; charset:UTF-8
should fix the issue for good I think.
At some point David raised the status of special attribute in XML:
---------------
AFAIK, there's nothing special about an href attribute; it just seems
like a good convention. I thought that XML treated 'id' attributes
special, but that doesn't seem the case either (AFAICT, the XML spec
only talks about attributes with type ID, of which an element can have
at most one) But an 'id' attribute is probably still a good one to
avoid, since the informal expectaton is that its value is unique within
the document.
---------------
True, and since those documents don't reference a DTD (and shouldn't)
by default all attributes are just CDATA (i.e. any character data) ...
except if you use the 'relatively' new xml:id construct instead of id
http://www.w3.org/TR/xml-id/
where new stacks compliant with this spec will recognize xml:id as being
of type ID (and hence validated as such so be careful of what you put
in the attribute) but in that case it can give a meaning to a fragment
identifier for the document
{base}/vms/#{id}
assuming in the collection you used
<vm href="/vms/{id}" xml:id="{id}">
...
then the fragment #{id} would identify that <vm> within that collection.
I'm not sure how useful that might be, and how the REST community see
xml:id (I don't remember seeing flames from them at least :-)
Note, I would keep all references from REST replies relative in the
sense that adding the protocol and host are superfluous, but always
use an absolute path to avoid decoding errors i.e. never use something
like href="../vms/{id}" always href="/vms/{id}" (it's very easy to get
the base wrong, and forcing the base computation can be tricky !)
One of the thing which might be difficult is how much information to
expose at the collection level, versus what really should only be
provided by fetching the vm URL, if you put too much, you inflate the
size of the data, and make its value less cacheable since expiring
faster, if you put not enough you end up always browsing the full set of
VM and that can be disastrous. The limit might be to provide enough
information that an UI representing the data don't need to refetch
each vm URL individually, think of the virt-manager main view for
example.
Okay, I still have much to read, thanks for listening :-)
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
14 years, 1 month
JSON and YAML support
by Mark McLoughlin
Hey,
Enough of this XML stuff! :-)
I've just committed the first cut at JSON and YAML support.
The JSON support is using the BadgerFish format at the moment, but we
should switch that to the Jettison Mapped Convention when we can get it
working
So, JSON looks like:
{"vm":
{"actions":
{"link":
[
{"@rel":"shutdown","@href":"http://{server}/vms/1/shutdown"},
{"@rel":"start","@href":"http://{server}/vms/1/start"},
]},
"hostId":{"$":"1"},
"id":{"$":"1"},
"link":{"@rel":"self","@href":"http://{server}/vms/1"}
}
}
and YAML looks like:
!vm
actions: !actions
links:
- !link
href: "http://{server}/vms/1/shutdown"
rel: shutdown
- !link
href: "http://{server}/vms/1/start"
rel: start
hostId: "1"
id: "1"
link: !link
href: "http://{server}/vms/1"
rel: self
As David suggests, we should carefully document the XML format and then
just describe the the XML to JSON/YAML mappings.
Cheers,
Mark.
14 years, 1 month
Actions now added
by Mark McLoughlin
Hey,
I've added deltacloud-ish actions. See:
http://git.fedorahosted.org/git/?p=rhevm-api.git;a=commitdiff;h=c5c2bbb844
It winds up looking like:
<vm href="http://{host}/vms/{id}">
<actions>
<link type="application/xml" rel="shutdown" href="http://{host}/vms/{id}/shutdown"/>
<link type="application/xml" rel="start" href="http://{host}/vms/{id}/start"/>
...
</actions>
</vm>
Feedback appreciated, particularly about whether the addition of an
@Action annotation is pure craziness :)
Cheers,
Mark.
14 years, 1 month