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