I don't like the idea of adding attributes to the existing service
element because we still need a way to specify response hyperlinks
(HATEOAS), plus I imagine other sub-elements and additional attributes
will be needed as we build it out more.
I prefer to keep the attribute names similar to the names used in the
specification - so they will make sense to developers who are familiar
with REST. I came up with a better name for the hateoas-attributes
element: response-hyperlink.
-Adrian
On 5/6/2011 2:23 AM, Jacopo Cappellato wrote:
What about adding the "noun" and "verb" attributes to the "service" element?
BTW in order to write a good application I suspect that a lot of services
should be refactored to better fit into a REST based application.
A good candidate for a prototype could be the Webtools' "Entity Data
Maintenance" application: we could rewrite it to work with RESTful URIs like
webtools/entities/
webtools/entities/orderheaders/
webtools/entities/orderheaders?orderTypeId=SALES_ORDER
webtools/entities/orderheaders/10010 (CRUD using GET/POST/DELETE)
webtools/entityrelations/orderheader (this will return URLs of related entities)
We could provide different representations for the responses (and this could also serve
to reimplement the "XML data export" part).
Kind regards,
Jacopo
On May 5, 2011, at 5:06 PM, Adrian Crum wrote:
I'm thinking we could have a new element for the service definition:
<service name="createExample" default-entity-name="Example" engine="entity-auto"
invoke="create" auth="true">
...
<rest-attributes resource="example" method="POST"/>
...
</service>
The presence of the rest-attributes element implies the service can be exported
via REST.
So, a new Example can be created by sending an HTTP POST request to
https://mydomain.com/rest/example
"HATEOAS" can be implemented with child elements:
<service name="createExample" default-entity-name="Example" engine="entity-auto"
invoke="create" auth="true">
...
<rest-attributes resource="example" method="POST">
<hateoas-attributes resource="exampleItem" .../>
...
</rest-attributes>
...
</service>
<service name="createExampleItem" default-entity-name="ExampleItem" engine="entity-auto"
invoke="create" auth="true">
...
<rest-attributes resource="exampleItem" method="POST">
<hateoas-attributes resource="example" .../>
...
</rest-attributes>
...
</service>
The REST servlet will use the hateoas-attributes elements to construct URLs for
the REST response.
What do you think?
-Adrian
On 5/4/2011 6:24 PM, Adrian Crum wrote:
Thanks Scott!
I agree - the REST URLs (or URIs) should represent resources and the HTTP
commands should represent actions taken on those resources. I guess I was
trying to take a shortcut by having REST URLs point directly to OFBiz services.
So we need a way to map REST URLs to the appropriate services. Maybe the
service definitions could include a REST resource identifier. That should be
easy to implement.
How could we implement something like the "Link things together" section of
this article:
http://www.infoq.com/articles/rest-introduction
(That question is for the community, not Scott specifically).
-Adrian
On 5/4/2011 5:54 PM, Scott Gray wrote:
Hi Adrian
My limited understanding is that RESTful URLs should point to a data resource rather than
service logic resources. The verbs (HTTP request method) are used to indicate the type of
operation (CRUD) to be performed on the noun (data object). So you'd have something like
a URL that points to say the "person" resource and using that URL you can GET a
person(s), create or update (POST) a person(s) and DELETE a person.
If what I say above is correct then what OFBiz lacks primarily is the ability
to map a verb and nouns combination to a specific service. I believe David has
taken some steps to resolving that in Moqui which we could achieve by altering
the way we define services or alternatively as a stop-gap measure we could
introduce an additional mapping layer which defines resource end-points and
maps the request type to the appropriate service (perhaps not so easy for POST
operations that use a create or update approach but possible by checking for
the presence of specific record identifying parameters to indicate an update).
What you've described below sounds more like a regular HTTP web service
approach that just makes a bit more use of the request headers than we do
currently.
Regards
Scott
HotWax Media
http://www.hotwaxmedia.com
On 5/05/2011, at 12:11 PM, Adrian Crum wrote:
I'm working on a project that might require accessing OFBiz services via REST.
I know there have been discussions about using Axis, and Chris Snow was able to
get a REST library to work with OFBiz. Please correct me if I'm wrong, but it
seems to me OFBiz already has most of what is needed to implement REST, so
there shouldn't be any need to use any additional libraries.
From what I understand, REST services are simply HTTP requests sent to a
particular URL to invoke a particular service. The request response contains
any requested data in a format the REST client specified in the request. The
HTTP commands GET, POST, PUT, and DELETE are used in the requests. The meaning
of the REST HTTP commands are server-specific.
So here is what I'm thinking: Let's say we want to access OFBiz services via
REST. We don't need to support the PUT and DELETE commands because the services
themselves determine what actions will be performed on the data. So, let's say
that a GET command gets information about the service, and the POST command
invokes the service.
From my perspective, this could be implemented in two different ways: a REST
servlet or a REST view handler. In either case, the basic flow would be
something like:
1. Get service name from request URL, look up service model. If export is
false, return 404.
2. If service model auth is true, get credentials from HTTP header. If no
credentials, return 401. If credentials are found, attempt to log in user. If
login fails, return 401.
3. If command is GET, get Accept content type(s) from HTTP header, use those to
find a converter. Convert service model info to requested type and put it in
the response.
4. If command is POST, get content type from HTTP header, use that to find a
converter. Convert POST data to service parameters and invoke the service. Get
Accept content type(s) from HTTP header, use those to find a converter. Convert
service result to requested type and put it in the response.
So, we could implement REST with existing artifacts - no additional libraries
are needed (except maybe for data conversions).
What do you think? I'm not a REST expert, so comments are welcome!
-Adrian