One last thing about this...

The idea of adding a REST element to the service definition was based on convenience, but some service engine "purists" might believe that it doesn't belong there. An alternative would be to put the element in a separate file that maps REST requests to services, but then that file could become "out of sync" if the services referred to in it are deleted. An example of where that approach is taken already is in the controller.xml file - where request events are mapped to services. Maybe the controller.xml file should be the place where REST requests are configured. I'm completely undecided about that - I'm not sure which way is best. Any input from the community would be appreciated.

-Adrian

On 5/6/2011 2:14 PM, David E Jones wrote:
Yes, POST semantics are more flexible in some ways in that it implies that the 
resource in the message is added (created) under the location specified, and 
because of this it supports sending multiple resources to be added there. In 
theory there could already be something under the location with the same name, 
causing an update or replacement, but that seems to be ignored, making POST 
seem slightly more natural as a create instead of an update.

PUT is for placing the data at the location and I believe does not support 
multiple resources in the message, and would either create if nothing was at 
the location or update if something was there, and I suppose that's why people 
consider it more for update instead of create.

Either way, it's messed up IMO... but that goes back to my bias against RESTful 
services as it seems to be using a protocol for something that it what was not 
intended or designed for, and it turns into repeated efforts to put round pegs 
in square holes (or do I have that backwards?).

-David


On May 6, 2011, at 1:52 PM, Adrian Crum wrote:

Thanks David!

I was thinking we would need a servlet for this - because some of the REST 
semantics are in the HTTP headers as well as in the HTTP method. From what I've 
read, the generally accepted convention is that POST is a create operation, and 
PUT is an update operation. But I agree with you that we need to have the 
method meaning clearly documented.

-Adrian

On 5/6/2011 10:40 AM, David E Jones wrote:
One bit of documentation I like that shows clearly how the RESTful services are 
defined and what the messages look like is the Adility API docs, such as this 
one:

http://apidoc.adility.com/submission-api

The nice thing (and actually many RESTful API docs do this) is that they list each 
"service" for that service they tell you which HTTP method is used, and what 
the path to the resource is. The point of this style of mapping is because the HTTP 
methods (GET, PUT, POST, DELETE) don't really map naturally to, well, to anything. They 
don't even map well to CrUD operations because PUT and POST are really meant for 
submitting resources and both could technically result in a create or update, though they 
have different intended uses and semantics that confuse the matter further.

So, it's generally necessary to define service "locations" (and mappings to the 
actual service) not just as a URL, but with a HTTP method and URL pair.

On a side note, to handle all HTTP methods we'll need to either modify the 
ControlServlet, or (maybe preferable, and what I've done on other projects) 
just use a totally separate servlet that is meant for the RESTful API. In other 
words, because RESTful stuff relies more on lower level HTTP stuff it is quite 
different from the more generic approach the ControlServlet uses.

-David


On May 6, 2011, at 9:39 AM, Adrian Crum wrote:

Here is the Amazon REST API - it could be a good source of ideas for 
implementation:

http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAPI.html

-Adrian

On 5/6/2011 7:33 AM, Jacques Le Roux wrote:
After having read the response hyperlinks article I tend to agree with Adrian. 
HATEOAS seems to me a really important feature of
REST
I have still to read completly the 1st article Adrian mentionned though. I mean 
http://www.infoq.com/articles/rest-introduction

And yes I also prefer response-hyperlink instead of hateoas-attributes

Jacques

From: "Adrian Crum"<adrian.c...@sandglass-software.com>
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

Reply via email to