BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Introducing: Restful Objects

Introducing: Restful Objects

This item in japanese

Bookmarks

Restful Objects is a public specification of a hypermedia API for domain object models. Version 1.0.0 of the specification has just been released and may be downloaded from here, and there are already two open source frameworks that implement the specification - one for the Java platform and one for .NET.

How does Restful Objects differ from other RESTful standards or frameworks - such as the JAX-RS (JSR311) for the Java platform, or Microsoft’s Web API for .NET? While such frameworks typically help in abstracting away pure network issues, they don’t ensure any uniformity in the structure of the resources defined to interact with different types of domain object. And they provide little or no support for what is arguably the most important principle of RESTful systems: "hypertext as the engine of application state", or HATEOAS. In plain language this means that it should be possible to access the entire functionality of the system just by following hypermedia controls (links) from a home resource. Perhaps the closest match to what Restful Objects is attempting is OData. However, the big difference is that while Odata is really targeted to CRUD (Create, Read, Update, Delete) functionality, Restful Objects provides access to the full behaviour (the methods) of the objects.

The new frameworks that implement the Restful Objects spec don’t just make the task of writing a HATEOAS-conformant API to a domain object model easier - they actually eliminate the work altogether! You can literally take a domain object model - written as plain-old Java objects or plain-old C# objects respectively - and create the complete RESTful API to them in minutes.

Moreover because the resources and representations provided by these frameworks conform to the public specification, it means that a client written to work with a server running one framework will work with the other also. Our hope is that over the next few months we will see more server-side implementations of the Restful Objects specification (we know of at least one other party planning to do so). We're also starting to see the emergence of standard client-side frameworks to consume a Restful Objects API; more on that later.

Applicability and benefits

The Restful Objects specification is most likely to appeal to developers who use domain-driven development (DDD) and who therefore already have or are developing a domain object model, and who also want to provide some sort of RESTful API to this model. Our own experience of DDD involves very large scale domain object modeling [1, 4, 5], with the majority of the behaviour encapsulated as methods on the domain entities. We are looking forward to using Restful Objects to further leverage such domain model assets.

Apart from the enormous savings in effort, there are a couple of other benefits to be gained from using a framework that implements the Restful Objects spec:

  • Testing. Since all business logic is expressed only in domain classes, such business logic may be tested using fast and cheap in-memory unit tests. In contrast, if a RESTful API is custom-written and tuned to specific use cases, then it can only be effectively tested through (slower) integration tests running across a webserver.
  • Documentation. Because Restful Objects is driven from a domain object model, it can be documented using established techniques (eg UML, or simply Javadoc/Sandcastle). This is far preferable to inventing some new notation to explicitly document a hand-crafted RESTful API.

Before we go on, we should also say that Restful Objects is agnostic with respect to the semantics of the domain object model. So, whether you believe that domain objects should represent the entities of the business, or whether you believe that there should be a separate ‘resource model’ representing instances of use-cases, say - the Restful Objects specification is equally applicable. For simplicity, in this article we'll predominantly use examples that assume the former (domain objects as entities), but we'll revisit this topic later on in the article.

Resources

In the Restful Objects specification each domain object is a resource; for example the following URI addresses a customer with the Id of 31:

~/objects/customers/31 

where ~ is the server address (such as http://myserver.com), customers defines the type of object and 31 is the ‘instance identifier’ of that type. The spec doesn't define the format of this identifier; any unique string will do. Why the need for /objects? This is to distinguish the resource from other top-level resources, including services (singleton objects such as repositories and factories that have methods but no properties) and domain-types (type metadata); each of these top-level resources has their own sub-resource structure.

Each object resource will have a number of sub-resources representing members of that object. So:

~/objects/customers/31/properties/dateOfBirth

addresses a particular Customer's date of birth, while:

~/objects/customers/31/collections/orders

addresses the collection of Orders associated with the Customer. The table below shows the object, property, and collection resources mapped against the HTTP methods used to access them. Where no useful meaning could be assigned to a particular HTTP method then a 405 error is specified.

 

Object
resource

Object
Property resource

Object
Collection resource

GET

Object summary

Property details and value

Collection details and content

PUT

update or clear multiple property values

update or clear value

add object (if collection has Set semantics)

DELETE

Delete object

clear value

remove object from collection

POST

n/a - 405

n/a - 405

add object (if collection has List semantics)

The above analysis is hardly innovative - many bespoke RESTful APIs feature something similar. The Restful Objects specification breaks new ground, though, in applying the same approach to object ‘actions’ - meaning those of an object’s methods that are to be accessible through the RESTful interface. To the extent that this is tackled at all in other designs (for example in [2]), it is usually to map an action's invocation to HTTP POST. Our objectives led us to distinguish between providing information about an object action - such the set of parameters required - and actually invoking the action. Thus, the URL:

~/objects/customers/31/actions/lastOrder

describes an action that will retrieve the last order for customer 31, while:

~/objects/customers/31/actions/lastOrder/invoke

is the resource to invoke this action.

We also realised that requiring all actions to be invoked with a POST was not making correct use of HTTP: what about idempotent actions, or query actions that just retrieve other objects (sometimes described as ‘side-effect free’)? The table below shows how we resolved this:

 

Object Action resource
(information)

Object Action Invoke resource

GET

action prompt containing details such as parameters and HTTP method for invocation

Invoke - if the action is known to be query-only (side-effect free)

PUT

n/a - 405

invoke - if the action is known to be idempotent, but not query-only

DELETE

n/a - 405

n/a - 405

POST

n/a - 405

Invoke an action that is not known to be query only nor idempotent

In some domain models, most of the behaviour (business logic) is implemented on services, with domain entities acting as little more than data structures passed to and from the service actions. The Restful Objects specification copes well with this pattern; the only difference is that the URL would identify a service instance rather than a domain object instance. However, the spec copes equally well with a pattern where most of the behaviour is implemented as methods on ‘behaviourally-rich’ domain objects; services then play the much more minor role of providing access to objects (finding existing objects, or creating new ones).

Representations

Each resource returns a representation; the Restful Objects spec defines that these representations are in JSON (JavaScript Object Notation). For resources called with a PUT or POST method, a representation must also be provided as a body to the request, describing how the resource is to be modified.

The specification defines a few primary representations:

  • object (which represents any domain object or service)
  • list (of links to other objects)
  • property
  • collection
  • action
  • action result (typically containing either an object or a list, or just feedback messages)

and it also describes a small number of secondary representations such as home, and user. Each of these representations has a formal media type, exposed in the HTTP Content-Type header. For domain objects, this takes the form:

   application/json;profile="urn:org.restfulobjects:repr-types/object";
   x-ro-domain-type="http://~/domain-types/customer"

Formally, this is of type application/json, with two optional parameters: profile, and x-ro-domain-type. These two parameters provide additional semantics to the consuming client, and can be thought of as layered one on top of another. At the lowest level, application/json tells the client merely that the payload is JSON. For some clients, such as developer plug-ins to browsers, this is all the information that is required. On top of this, the profile parameter indicates that the representation is of a domain object. Finally, the x-ro-domain-type parameter indicates the type of the object: in this case a Customer. A client might use this to customize the user interface, or just to verify that the representation returned is the one expected. Incidentally, the specification uses the .x-ro- prefix to minimize namespace conflicts whenever there is no existing or draft standard that can be leveraged. This necessarily gives rise to a number of custom parameters and query strings; Restful Objects defines no custom HTTP headers, however.

Links

In line with the HATEOAS principle, each representation contains links to other resources, and each of these links has a rel parameter defining the nature of the relationship. The specification re-uses several IANA-defined rel values (for example, self, up, describedby), plus some custom ones. For example:

   urn:org.RESTfulobjects:rels/details;action="placeOrder"

defines a link from an object representation to a resource for an action on that object. The prefix:

   urn:org.restfulobjects:rels/details

is sufficient for a generic client, while the additional parameter action - indicating in this case that this link is for the placeOrder action - may be of use to a bespoke client.

Putting all the above together, the table below shows a typical flow through a set of resources to accomplish some user goal.

Description

Method

URL

Body

Returned
representation

Go to the home resource

GET

http://~/

-

Home Page

Follow link to list of Services available

GET

http://~/services

-

List (of links to Services)

Follow link to the ProductRepository service

GET

http://~/services/ProductRepository/

-

Service

Follow link to ‘Find By Name’ action

GET

http://~/services/ProductRepository/
 actions/FindByName

-

Action (to be rendered in the UI as a dialog)

Invoke this (query only) action with "cycle" as the parameter

GET

http://~/services/ProductRepository/
 actions/FindByName/
 invoke/?Name=cycle

-

Action result in-lining list of links to matching Product objects

Follow the link to one of the Product objects in the collection

GET

http://~/objects/product/8071

-

Object (representing a Product)

Invoke the (zero parameter) action ‘AddToBasket’ on this object

POST

http://~/objects/product/1234/
 actions/AddToBasket/invoke

-

-

Invoke the action ‘ViewBasket...’ on the BasketService

GET

http://~/services/BasketService/
 actions/ViewBasketForCurrentUser/
 invoke

-

Action result in-lining list of links to Item objects

Modify the Quantity property on the item just added

PUT

http://~/objects/orderitem/1234/
 properties/Quantity

Property repres'n with value=3

-

Delete a (previously added) item from the Basket

DELETE

http://~/objects/orderitem/517023

-

-

Server implementations

Earlier we mentioned two separate open source frameworks that implement the Restful Objects specification. Restful Objects for .NET is a complete implementation of the specification, in beta only because it makes use of the Microsoft Web API framework (part of ASP.NET MVC4 - in ‘RC’ stage at the time of writing). The second framework, Restful Objects for Isis runs on the Java platform; this framework is working, but currently implements an earlier draft of the specification and needs further development and testing before release. We are actively involved in the development of these frameworks.

With each of these frameworks, it is possible to take a domain object model, written as POCOs and POJOs respectively, and create a complete RESTful API conforming to the Restful Objects specification, without writing any further code. An online video recording (using the .NET framework) shows this being done in just a few minutes.

This is possible because both of the frameworks build upon existing frameworks that implement the naked objects pattern - whereby an object-oriented user interface is created automatically from a domain object model using reflection, with public methods made available (by default) as user actions. The new Restful Objects frameworks reflect over a domain object model in a similar fashion, but render the objects’ capabilities as a RESTful API rather than a user interface. In both cases, they delegate to the existing frameworks (Naked Objects for .NET, and Apache Isis respectively) the responsibility for reflection, for object persistence, and other cross-cutting concerns.

The new frameworks both recognise some simple domain object coding conventions, and annotations (‘attributes’ in .NET). Any public method on an object, for example, will by default be made available as an action in the Restful Objects API, but this may be overridden by annotating the method as Hidden. If an object defines a public method foo([params]) and also a public method validateFoo([params]), the latter will be recognised as providing logic for validating parameters supplied to the former before it is executed.

Both frameworks also provide fine-grained authorization based on the user’s identity and/or roles. If, for a given domain type, the user is not authorized to view a given property, collection or action, then in the corresponding representations the links to that object member will never be rendered for that user. Were the user to attempt to gain access by constructing the URL for the resource directly, they would be returned a 404 error; if the user has permissions to view the object member, but not to modify it, then attempting the latter would return a 403.

The source code for Restful Objects for .NET can be downloaded from Codeplex or the framework may be installed as a NuGet package; Restful Objects for Isis may be downloaded as source code or installed through a Maven archetype.

For any developer already using Naked Objects for .NET or Apache Isis, the new frameworks mean that they can create a RESTful API to their existing domain models with literally minutes of effort. But our intent was always to appeal to developers with no knowledge of, nor interest in, the naked objects pattern, and we are indeed seeing interest from such developers.

Clients

Most of our development effort to date has been focused on the server side - the code that generates a Restful Objects API from a domain object model. We have also done some limited work on client applications that consume such APIs.

In one example, the client is a conventional web application (written using ASP.NET MVC), where the controller methods make calls to a Restful Objects API implemented on another server. We hope in future to develop a small client-side application library for making the calls to the Restful Objects server and for transforming the returned JSON representations into objects that can be manipulated by C# or Java, say.

Another example client we have written is a ‘single-page application’, consisting of a single web page, containing just a few lines of static HTML, and supported by a rich set of JavaScript functions using JQuery. The JavaScript makes the calls to the Restful Objects API on a server and renders the results as HTML in the browser. Again, we hope in future to be able to write a small JavaScript application library, specific to consuming a Restful Objects API, but drawing heavily upon JQuery - or perhaps someone else will pick up that baton.

The generic nature of the Restful Objects specification suggests another possibility: generic clients that can work, unmodified, with any domain model via the RESTful API. We are aware of three different open source generic clients already under development, and these are listed on the Restful Objects website. All of them are single-page apps, written in JavaScript and using existing libraries. The JavaScript code within of these generic clients could also be used as the basis for creating one or more custom clients also. The three generic clients have very different styles of user interaction. A screenshot from one of them - A Restful Objects Workspace (AROW), being developed by Adam Howard, is shown below:

(Click on the image to enlarge it)

Counter arguments

The idea of exposing domain entities via a Restful API is controversial. Some commentators have suggested that it is a bad idea; or that it creates security holes; others have even suggested that it is not possible to create a true Restful API that way. Let’s look at those arguments in detail.

Rickard Öberg has asserted that exposing domain entities as resources "cannot be HATEOAS because there is no sensible way to create links between resources that expose the application state" [3]. But this is plainly not true: Restful Objects exposes entities as resources; is fully HATEOAS; and has very clear rationales for the links.

Jim Webber has asserted that even if is possible, it is a bad idea because this results in a tight coupling of client and server, whereas in a Restful system client and server should be able to evolve independently [6]. He and others argue that you should expose only ViewModels and/or objects representing use-cases, both of which should be versioned, and which effectively insulate the client from underlying changes in the domain model.

We suggest that this argument, while not totally wrong, is being applied indiscriminately. The truth, we believe, is much more nuanced: there are situations where this line of argument is valid, but many where it is not. Two factors need to be considered.

The first is whether the client and server are both under the control of the same party. For a publicly-accessible Restful API - such as one operated by Twitter or Amazon - then the server and clients are owned by (many) separate parties and here, we agree, that exposing domain entities is not a good approach. Restful Objects, however, can work perfectly well with view models and/or use-case objects in this case, and these patterns are discussed in more detail in the specification.

However, there are a great many potential uses of Restful APIs where client and server evolution are controlled by the same party - in the form of enterprise applications for primarily internal use. Here, exposing domain entities is not only safe, it is actually a good idea. Such applications, which fall into the category of ‘sovereign’ systems (as defined by Alan Cooper), typically need to give the user access to a much broader range of data and functionality than in a public-facing (or ‘transient’) application.

The second factor is whether the client is ‘bespoke’ (written specifically to work with a particular domain model) or ‘generic’ (capable of working, unmodified, with any domain model). To date, almost all clients consuming Restful APIs, whether for intranet or public internet, are bespoke - so there is a need to insulate them from changes to the domain model. But that is not true of a generic client, which will respond automatically to changes in the domain model. To date, few people have considered the possibility of generic clients, though, because there was no comprehensive standard against which they could be written. We suggest that the concept of a generic client is actually more in-line with the spirit of REST (and the letter of it too) than a bespoke client. After all, at one level, a web browser is just a generic client to a restful interface, operating at a document level. Restful Objects enables the idea of a generic client operating at a higher level of abstraction: that of a domain object model.

Portraying these two factors as a 2x2, as shown below, we can see that if you are dealing with an intranet application and/or a generic client, then exposing domain entities through a RESTful API is both safe and effective. Only where you are working on a public internet application and with bespoke clients is it necessary to heed the advice that domain entities should be entirely masked by ViewModels and/or use-case objects, to insulate clients from server changes.

                  Deployment:
Form of client:

Intranet

Internet

Generic

Exposing domain entities is fine

Exposing domain entities is fine

Bespoke

Exposing domain entities is fine

Expose only versioned ViewModels and/or use-case objects

To reiterate: Restful Objects is equally applicable to all positions on this grid. The fact that the bottom-right corner has received most attention to date is, we suggest, more a reflection of the difficulties of building bespoke Restful APIs than an inherent limitation. Another common nostrum - that Restful APIs can only be built for applications that have a small, tightly-defined, state-transition diagram - is further evidence of people thinking only in that box.

Öberg has further suggested that exposing the domain entities as a RESTful API cannot work for a public application because of authorization issues, citing the example where access to a ResetPassword action may be regulated by role, but access to a ChangePassword action must be restricted to a specific user. This particular example is actually trivial to code in both of the Restful Objects framework implementations described above. We suggest that a better example for the point that he is trying to make would be access to a specific object instance, rather than a method. This is a common need in public-facing systems: for example where a user must be able to access their own ShoppingBasket, but not be able to access anyone else’s ShoppingBasket just by guessing at the URL.

While neither of the two Restful Objects implementations currently support instance-based authorization per se, there is another perfectly viable solution to this problem. As we mentioned earlier, the form of instance identifiers in URLs is not prescribed in the Restful Objects spec. It follows that this part of the URL may be encrypted by the server, for example using a session-generated private key. Invoking a service action resource to return MyShoppingBasket might then return an object representation whose "self" link was:

~/objects/baskets/xJDgTljGjyAAOmvBzIci9g

The URL for the Total property on that shopping basket would therefore be:

~/objects/baskets/xJDgTljGjyAAOmvBzIci9g/properties/Total

So parsing of resource identifiers remains straightforward, but it would be effectively impossible to retrieve another Basket directly. Certainly this is less pretty, but it is worth pointing out that REST is not about creating ‘pretty’ URLs. As Tim Berners-Lee has stressed, apart from the server address, URLs should be treated as opaque; it's the "rel" value that matters. That’s part of the point of HATEOAS.

In both of the two Restful Objects frameworks described in this paper we plan to make session-key encrypted instance identifiers as a configurable option..

Conclusion

Creating a RESTful API to a large enterprise system has, to date, been a very expensive exercise in development terms - requiring huge resources in design, development, testing and documentation. Using a framework that implements the Restful Objects specification means that the whole exercise becomes almost trivial - leaving the developers to concentrate their efforts where it is most needed - on the domain object model.

Moreover, the standardization of resources and representations encouraged by the Restful Objects spec opens up a huge opportunity for client-side libraries, that will work with any Restful Objects server, and even for completely generic clients, that will work for any application coded to the standard.

We hope you'll explore the Restful Objects specification and the framework implementations, and we'd be delighted to hear from anyone interested in writing a new open source framework or library designed to conform to the Restful Objects spec.

References

[1] Haywood, D, "Domain-driven design using Naked Objects", 2009, Pragmatic Bookshelf
[2] Masse, M. "REST API Design Rulebook", 2011, O’Reilly
[3] Öberg, R, "The Domain Model as REST Anti-pattern"
[4] Pawson, R. "Case Study: Large-scale pure OO at the Irish Government", QCon London 2011 presentation
[5] Pawson, R, "Naked Objects", 2004, PhD thesis, Trinity College, Dublin.
[6] Webber, J, "Rest and DDD".

About the Authors

Richard Pawson has worked in IT for 35 years  -  claiming to have been the very first person in Europe to write and run a program in a Microsoft language. As well as periods spent in advanced robotics, toy design, and technology journalism, he was 14 years with Computer Sciences Corporation as Director of Research. His 2004 PhD thesis is the definitive reference on the 'Naked Objects' architectural pattern, and since then he has been Managing Director of Naked Objects Group. He lives in Henley-on-Thames, UK, in a house that he designed using Christopher Alexander's A Pattern Language.
 

Dan Haywood is a freelance consultant, developer, writer and trainer, specializing in domain-driven design, agile development, and enterprise architecture on the Java and .NET platforms. He's a well-known advocate of Naked Objects, and a leading committer on the Apache Isis project.  Dan is the author of the Restful Objects spec, and has also written a number of books on DDD and OO.  He lives near Oxford, UK.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • My humble opinion on the topic.

    by Alexandre Roba,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Restfull objects as I understood it from your article are Entity services through a REST API. It brings the added value of REST on those entities exposed via Entity Services. Well I might be a bit extreme here but I found the entity services to be a sort of anti pattern and should be avoided :( Rest is meant to access resources not objects. Objects are composed of state and operations. What I see here is RESTfull DTO and RESTfull functions not RESTfull objects. This of course only translate what I think of it. I haven't found a proper way to have my domain object be access as resources. Imagine this. I get my domain object through an open API. I manipulate my domain entity in any device that can access all the required resources needed for this manipulation and then send back my resource back to the master. Sounds great for me but It will bring a lot of issues like concurency, race condition... Anyway it is an interesting article but not sure if the concept is applicable.

  • Re: My humble opinion on the topic.

    by Richard Pawson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I'm not sure I fully understand your point. The 'Domain Object Representation' returned by the domain object resource contains both its properties and also all of the actions that that user can invoke on that object - in the form of links to action resources on the server - which may be to instance methods on that object in the server, or to services that provide methods for that object. In that sense I think it is as object-oriented as it is possible to be on REST. I recommend that you take a quick look at the RO specification itself for further clarification.

  • Very Cool

    by Adam Bell,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I don't think this technology will work for everybody, but for internal Line of Business Apps, it sounds promising. The metaphor of Odata++ is great.

  • Handling concurrency issues

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    To your point about concurrency etc... the standard HTTP approach for this is to use If-Match and ETags headers, returning a 412 status code if the resource has changed in the meantime. The RO spec defines the same usage; see section 2.15.

  • RPC?

    by Mark Davidson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    ~/objects/customers/31/actions/lastOrder/invoke.. isn't this RPC?

  • No, RO is not an RPC system

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    No, that's a URL. Depending on the semantics of the action, it can be invoked either with a GET if query-only (19.1 of the spec), a PUT if idempotent (19.2), or a POST if neither (19.3). Contrast this with SOAP (which I do agree is an RPC) where everything is a POST.

    Moreover, the way that you get to that URL is by following links, with the appropriate "rel" attribute (2.7 of the spec). In this way the spec defines a fully HATEOAS API.

  • Re: No, RO is not an RPC system

    by Mark Davidson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Sorry my bad.. I was under the impression that the URIs should reference nouns not verbs.

  • Re: No, RO is not an RPC system

    by Ryan Riley,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    For REST, a URI should reference a resource. The statement above that resources are mapped to domain objects is misleading at best. It's more that every aspect of a domain model appears to be mapped as a resource. In other words, your domain model is blown apart and every piece made into a resource. I'm not you can really differentiate that from RPC, though, as I wouldn't agree that those pieces are resources. Also, given the encapsulation property of OO, I don't think there's any way to map to REST directly. OO hides state, REST exposes state. They are the antithesis of one another.

  • RO only exposes the public properties of an object

    by Richard Pawson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    RO only exposes properties that are public - it does not expose private state. Whether/which properties of an object should be public - as distinct from hidden by actions - is down to the design of the model. RO doesn't care. You could hide all state and expose only actions - the resource/representation model is still fine.

  • Spiro - Single Page Interface for Restful Objects

    by Stefano Cascarini,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    For anyone interested: I have been working on another open source client for Restful Objects called Spiro. It takes the form of a single-page app and is written using backbone.js, underscore.js, and jsrender for templates.

    Spiro will function as a generic client for any domain object model with a Restful Objects 1.0 API. The models (spiro-models.js) can also be used as the basis for building a completely custom UI - using standard backbone.js patterns.

    This is a work in progress - it is far from complete - but the parts that are implemented work quite well. You can find the code and more details here: restfulobjects.codeplex.com/wikipage?title=Spir...

    (If you are on the .NET platform, you can also install it as a ‘pre-release’ NuGet package: nuget.org/packages/RestfulObjects.Spiro/0.2.0-beta

  • Any information that can be named can be a resource

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Per the doubt you express about which pieces of a domain object model can be resources and which not: "any information that can be named can be a resource" (Fielding).

    By that definition there's nothing wrong with the spec defining "the first name of a customer" as a resource, nor "the contents of a basket", nor, indeed "add to basket".

  • Re: RO only exposes the public properties of an object

    by Ryan Riley,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I think this view highlights a distinction in our views/definitions of "domain model". My domain models are primarily behavioral, thus exposing one of my domain models would, in fact, be akin to exposing an RPC service. If my model is just like a DTO, then sure, this could work for some people. I've never found that my domain maps very well, and I certainly wouldn't want to automate that process. My domain should be a good domain model. How I expose that domain may differ depending on the delivery mechanism, e.g. web, console, tests, etc.

  • Re: Any information that can be named can be a resource

    by Ryan Riley,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    We'll have to disagree. I wouldn't say "add to basket" is a "name." Also, while "first name of a customer" is a "name," I don't think I'd ever expose that as a resource. That greatly depends on what I'm trying to do. It's really just my opinion that I don't see automated mappings as providing a good design from an OO model. I applaud your effort to try, but I like finer control over the meaning of my resources. My exposed web api is just not the same as the underlying domain model, even though they are related.

  • The spec doesn't mandate that you expose a fine-grained domain model

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Appreciate this discussion, and you do raise a valid point in your last sentence: in some scenarios, the web api that one wishes to expose is not the underlying domain model.

    As we discuss briefly in the article and the spec discusses in more depth (section 29, 33.3, 33.4, 33.5), there will be cases (internet, bespoke clients) when what should be exposed is a resource model that mediates to but does not expose an underlying domain object model. This is much closer to the style advocated by Oberg and Webber.

    Even here, though, RO offers benefit: you can develop your resource models as pojos/pocos, which mediates to/from the underlying domain model. This resource model can be tested outside of a big web stack, and you save yourself having to ever go down to the lower level of abstraction (of JSON, HTTP headers etc etc). And, the REST API you get is going to be much more uniform than if you coded it up yourself.

  • Very Cool indeed

    by Jeroen van der Wal,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The Restful Objects spec was one of the drivers in choosing a platform to build our next generation business applications. Having the same pattern and API implemented on both Java and .NET enables us to deliver applications within our customer's platform constraints (we eventually chose Apache Isis as our primary framework). We're also glad to see some interesting projects starting up to create appealing viewers for the RESTful API. And another huge advantage we're getting from having a complete RESTful API is in migrating and exchanging data from (legacy) systems to the new Apache Isis applications.

  • From a RestfulObjects consumer

    by Adam Howard,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Just to add my two cents...

    The javascript frontend I'm working on needs to know one uri: the homepage resource. From there I can operate solely on rels and the defined media types[1].

    So to take the table under the Links section (read .../services as urn:org.restfulobject:rels/services):

    var ro = new RO.Client("/");
    var services = ro.findLinkByRel(".../services").follow(); // follow() figures out the correct HTTP method
    displayAsMenu(services);

    displayAsMenu will loop over each of the services and for each service it's member actions. Each action becomes a link in the menu that binds onclick to follow the .../invoke rel.

    The user may decide to click on the "Find by Name" link under the Products menu. The representation of that action tells me I need to ask the user for a name.
    After requesting the .../invoke rel with the name parameter (the invoke link has told me I can do a GET meaning that the operation is safe) it returns a representation of product 8071 in this case.

    var result = anAction.findLinkByRel(".../invoke").follow(args);

    The Content-Type of the response is application/json;profile="urn:org.restfulobjects:repr-types/object" so I know I should display the result as a domain object.

    displayAsDomainObject(result);

    I'm not going to go through the whole table but you should get the idea. While the URI hierarchy may be important to providers of a RestfulObjects API, as a client developer I can happily live in HATEOAS land.

    [1] roy.gbiv.com/untangled/2008/rest-apis-must-be-h...

  • Re: Any information that can be named can be a resource

    by Mark Davidson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I have one more question. Re "any information that can be named can be a resource" - what information is being named by "add to basket"? If I understand correctly "add to basket" is an action. Is this really some information, a nameable resource? Sorry for asking seemingly stupid questions but your explanation seems to contradict some other articles on REST so I'm trying to make sense of it all. POST-ing data to a resource that represents a collection of items or a basket makes sense to me but I'm struggling to understand how these "domain actions" are RESTful. Thanks.

  • Domain action resources are a more general abstracion

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Lots of RESTful APIs try to map a domain object model in terms of CRUD operations: boiling things down to posting to collections, or updating/deleting existing resources. In RO terms, that would correspond to just manipulating state using the domain object property and collection resources.

    At the other extreme, there is advice to map everything in terms of state transitions of resource models (eg Webber's Restbucks article here on InfoQ). Nothing wrong with that for a public web api. The resources that represent these state transitions are much more akin to domain actions.

    RO aims to support both of these approaches, to make it easy to expose either your domain objects, or domain services that act as a resource model in front of a hidden domain model. Either domain objects or services can expose arbitrary business logic through their actions, and these actions can have arbitrary pre- and post-conditions.

  • Re: From a RestfulObjects consumer

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thanks for that, Adam. I've seen a few commentators on twitter look at the table in the article and surmise that RO is just a bunch of templated URLs. Thanks for dispelling that and demonstrating a little more completely how RO supports HATEOAS in your JS client.

  • Re: My humble opinion on the topic.

    by Alexandre Roba,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    This is clearly what I meant. The operation will not be executed on your object. It will be executed on the object on the server. That object might have changed since the last time you got it. Imagine this I get my object. Somenoe else also does. He change it or delete it. On what my operation will be executed? I do not have a RESTfull object. You a view on the state of the object and a link to an operation. You do not have an object as resource. Hope this will be more clear.

  • Valuable approach to exposing Domain Objects

    by Pedro J. Molina,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Richard, Dan congrats. I found the approach very valuable in order to provide standardized way of exposing an domain object model in a technology independent way.

    The capability of consume data and use a generic client to render the UI is also a great feature, useful for some kinds of applications.

    I have been working several years with object models and code generation to create server components and client ones. I have been exploring Web Services, REST, OData and different as ways of communicating service consumer with service producers. See InfoQ Multichannel UserInterfaces.

    So, definitely, I am going to explore the applicability of Restful Objects to our domain. I see a great potential in Restful Objects for simplifying integration between systems, in the way it standardizes many aspects.

    I have some questions about using RO in production systems:


    • 1. How authentication is handled in/(hooked with) RO? Standard HTTP/S authentication?

    • 2. When retrieving an object, all properties are returned always? Is there any mechanism available to limit or customize the amount of data (properties to be retrieved)? Different cases of use will have different information needs (aka DTO)

    • 3. Is there a way to retrieve a direct object subgraph (sample: Invoice, Customer, Invoice Lines and related Products) (in order to avoid 1+N calls over the wire)?

    • 4. When retrieving let’s say “Country.Customers” is there any protection like a paging scheme to protect us from directly getting 1 million of objects and therefore degrade the performance of the system?

    • 5. There are plans for advanced/dynamic queries over collection of objects? E.g: return the customers in Spain that have bought a given product X in the last 3 years.


    I think that addressing these concerns enables RO to be used in production systems.

  • Concurrency

    by Stefano Cascarini,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    So this is just concurrency - which is an issue for virtually all client-server systems. As Dan says Restful Objects uses standard http mechanisms to handle this (2.15 in the spec). The effect of this is that if the object has been changed on the server since you retrieved it your operation will fail with a 412 'precondition failed' prompting you to get a fresh representation.

  • Re: Valuable approach to exposing Domain Objects

    by Richard Pawson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thanks, Pedro.

    "1. How authentication is handled in/(hooked with) RO? Standard HTTP/S authentication?"

    The RO spec does not mandate/assume any particular flavour of authentication - you can use whatever you would for any RESTful API.

    "2. When retrieving an object, all properties are returned always? Is there any mechanism available to limit or customize the amount of data (properties to be retrieved)? Different cases of use will have different information needs (aka DTO)"

    The domain object representation returns all properties that the given user is authorized to see. If you want to limit what is actually returned then you can simply return a 'view model', specific to that context. There is quite a bit on this within the spec. That said, though View Models can certainly be useful, the need for them is commonly overstated. Provided you can be sure that the representation only returns data that the user is authorized to see (which is the case) then in many cases, it may be much simpler just to customize which properties are actually displayed in the client.

    "3. Is there a way to retrieve a direct object subgraph (sample: Invoice, Customer, Invoice Lines and related Products) (in order to avoid 1+N calls over the wire)?"

    The Restful Objects 1.0 spec does not explicitly provide for eager loading, but there is a substantial discussion of the recognised need for this at the back of the spec, and it will almost certainly be added in v1.1.

    "4. When retrieving let’s say “Country.Customers” is there any protection like a paging scheme to protect us from directly getting 1 million of objects and therefore degrade the performance of the system?"

    For the Restful Objects for .NET implementation, there is now such a guard. The default is 20, but you can override this globally. Right now if you want paging, you need to write actions that support it. But, again, it is likely that the next version of the RO spec will support paging explicitly - there is again a sketch of this in the last section of the spec.

    "5. There are plans for advanced/dynamic queries over collection of objects? E.g: return the customers in Spain that have bought a given product X in the last 3 years."

    Again, a likely future extension to the spec. You can certainly do such queries in the RO.NET implementation (using dynamic LINQ) - but it's not yet defined at spec level.

  • Re: Concurrency

    by Alexandre Roba,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    This is clearly the behavior you will have on an Entity services and unfortunately the same flaws. I'm not sure I will put my domain object accessible through an entity service or a RESTfull "object" API. I would put my commands and my views/projections available over a RESTFull API. Not My domain objects. but again this is only my opinion and I can understand that maybe for some simple business line application why not. Anyway thanks a lot for sharing this with us and keep being productive :)

  • Earlier discussions illustrate the 2x2 in the article

    by Richard Pawson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The earlier discussion (between Dan, Ryan & Mark) nicely illustrates, I think, the 2x2 table in the article.

    Ryan makes the point that for the domain models he designs would not be suitable to be exposed as a Restful API - he wants a custom-defined Restful API - and so the value of Restful Objects is much lower. I think it would be fair to say that Ryan is describing is in the bottom-right hand corner of the 2x2 in the article - a potentially public-facing API where you don't have control of the client.

    Dan makes the point that Restful Objects still works for this, and still adds value, even though that value might is not as great as in the other three. We know from personal experience that even with a 'dream team' of REST-heads and the best current tooling - writing custom RESTful APIs is extraordinarily labour intensive.

    But what does concern me is that so many RESTful practitioners seem unable to imagine the other three spaces on that 2x2. There is huge potential out there for REST - much more than the narrow concept of REST that most practitioners advocate right now. But the reality is that it would be almost impossible to work in those spaces without something broadly like the Restful Objects spec and frameworks that implement it automatically.

    Pedro (in another thread) has picked up on this. Organisations that do have good domain models (and, admitedly, that's not all that common) now have the potential to make those models accessible *within the intranet* via a RESTful API - both to facilitate integration between disparate systems, and to facilitate development of new clients. We know large organisations interested in RO on both counts. The point is that they could never consider doing this using a custom RESTful API - there would simply be too much effort involved in defining it, implementing it, and testing it.

  • Great stuff - possible application scenario?

    by Enrique Albert,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Dan &/or Richard,

    Congratulations on the new API, it is great news to see the NO continuously adapting new features.

    Can you indicate scenarios where you believe the Restful Objects API would be useful? If I have to develop an intranet solution, I can currently use the NO MVC, I can see the benefit of using the Restful Objects, for example, in system integration cases or if I had to develop a desktop client for example; that is, solutions that we normally use WCF services and DTOs; but, are there any other obvious scenarios besides those ones?

  • Other application scenarios

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    HI Enrique, I have a few.

    You mentioned system integration from a desktop client, which I'd see that more as two parts of the same app (with the client app being either bespoke or generic as fits). In domain-driven design (DDD) terms, that's one bounded context. But there's also system integration across bounded contexts. For example, one government department could invoke an RO API exposed by another government department. This would be a case where accessing the API through a resource model (bottom left of the 2x2) would be advisable.

    Another obvious case is using the RO API to support multiple client apps, eg a desktop app, a mobile app, etc. Here we are back into one bounded context (both the clients and server are owned by one team), and so could expose the underlying domain model directly.

    A slightly less obvious case is in migrating data; as Jeroen (above) mentioned, we're taking advantage of the RO API to start trial migrations of data from an existing system into a new Isis-based system. The RO API itself is throw-away, but the point is that it delegates to the main domain logic that we're building out. There's a bunch of benefits: the users get to validate the new system using data that is familiar to them, we get to validate our business logic, and we also get some stress testing for free.

    One final use case is in supporting phased migration from an existing system to a new system, which might take a number of years. We can wrap the existing system in an RO API, and put an RO API around the new system also. Clients written to the RO API can then access either the old system or new; 301 redirects can be used to hide the fact as to where the business logic invoked is being accessed from: existing system or new.

  • Here's a few application scenarios

    by Richard Pawson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Enrique

    Here's a couple of application scenarios that I'm personally interested in - but I'm hoping others might contribute more:

    1. As a lingua-franca for integration between multiple systems within an intranet. Great thing is these can be on different technology platforms and with different concepts of a domain model: one might be strongly object-oriented, one might be strongly service-oriented, and one might be little more than a wrapper onto a database.

    2. As a way to facilitate the development of new single-page apps for a single server. I'm astonished at how easy this is now proving to be once you have a comprehensive Restful API that delivers a consistent (small) set of JSON representations. Stef's work on the Spiro viewer (see earlier posting) shows this: he has a small set of backbone.js model objects that correspond to the RO representations, and that can form the basis of either a generic client or a bespoke client.

    3. Combination of 1&2. Dan proposed a very interesting pattern for this, described in the spec, and we have spiked it.

    4. Your own point about building desktop clients. I know of one organisation looking to use RO as the basis for communications between its WPF rich client and the server.

    Let's here some other ideas ...

  • Re: Here's a few application scenarios

    by Jacques Bosch,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Great article, and great to see RO maturing.

    >4. Your own point about building desktop clients. I know of one organisation looking to use RO as the basis for communications between its WPF rich client and the server.
    Perhaps there is another also, but I think we are the client that Richard is referring to. :)

    We are in the early phases of building a complex enterprise system that will consist of many different projects. The core of this system is built on Naked Objects MVC. We have a WPF desktop application that forms part of the same domain. We are going to do a spike to let this application work with the same core domain exposed via RO and auto generated C# proxies, although the WPF UI will be bespoke, not generic. I'll report back when we have actually tried this.

    We will also use RO to expose an API for our business partners to integrate with us.

    So far we have found NO MVC extremely beneficial and I think the extra power and flexibility that RO for .Net will add to the toolbox is very exciting.

    Thanks for the pioneering work!

  • Re: Any information that can be named can be a resource

    by Adam Howard,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    As you said earlier, it is true that URI's point to resources and resources should refer to nouns or "things".

    So, .../customers/31 is a thing, a .../repr-types/object. And .../customers/31/actions/lastOrder is a thing, a .../repr-types/action.

    An action like lastOrder, or addToBasket, has a representation with information like it's returntype and required parameters. It can also tell us where to go when we want to know the result of invoking the action, which will be a noun, as well as which HTTP method is appropriate. In that case we follow the .../rels/invoke link. I wonder if changing the name of the rel to something more noun-like, .../rels/invocation or .../rels/action-result, would make it clearer of the difference between action metadata (.../repr-types/action) and the value of the invoked action (.../repr-types/action-result). I wasn't involved in the development of the spec but came to it recently and the community has been very receptive to input about changes and future needs to support client side applications. So maybe this is something that can be discussed more.

    In the case of the other member types an object has: value properties, like a customer's name, reference properties, like a customer's billing address, or collections, like a customer's payment methods, they are all public getter methods on the domain object and getters share the semantics of being side-effect free and taking zero arguments. This means we know we can access their return value through a GET. It also means that in some cases we can even safely inline the value into the domain object representation. The RestfulObjects spec currently only defines this inlining for the simple value properties, but has a proposal (section 34.4) for extending the spec to allow inlining of references and collections, on demand.

    The reality is that all of this data is the result of invoking methods. The customer representation having a "name" property means there was a public getName method and the value is the result of invoking that method. The extra step that RestfulObjects took was to figure out how we can reason about accessing the result of any public method on an object, not just those with getter semantics. If other APIs do handle this they almost always hard-code the HTTP method to POST, which violates [1].

    [1] www.w3.org/DesignIssues/Axioms.html

  • Re: Earlier discussions illustrate the 2x2 in the article

    by Adam Howard,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    *I don't know if this is a coffee reality today but the example is good I think.*

    Suppose you walk into your favorite coffee shop and the line is long. You pull out your smartphone and go to the coffee shop's app, you tap the order button. You're then asked to choose what drink you want from a menu, then what extras you want in it, what size. You confirm your order, your credit card is charged, and in a few minutes your name is called out and you pick up your drink. The process you went through to order was very scripted: step 1, 2, 3, confirm.

    Now suppose you're not sure what you want to drink, so you wait in line. When you get to the register you ask: what has more calories, a shot of caramel or a shot of chocolate? The employee doesn't know but they can look it up on their computer. Caramel has 250, chocolate has 200. Yikes. Now you ask, what extras do you have that are under 100 calories? Back to the computer. Cinammon and fat-free milk. Ok, I'll have a fat-free latte with extra cinammon. I have $1.27 on this gift card. Put the rest on my credit card.

    The first scenario is a highly-scripted interaction that wants to guide the customer into placing their order as quickly as possible. This is a place where exposing a separate resource model is essential. The client may not be under your control and they don't fully understand your domain.

    POST .../MobileOrder
    {
    "DrinkName":"Mocha Frappacino",
    "ExtraName":"Caramel",
    "SizeName":"Venti",
    "CustomerName":"Bill"
    }

    The second scenario, however, requires the cashier to navigate around the domain of coffee ordering to answer the customer's questions and charge their credit card correctly. Having access to the full glory of the domain model allows the cashier, who understands the domain, to navigate directly to the answer. The coffee shop will probably build both the client and server and they will evolve together.

    GET .../extras/FindByName/invoke?Name=Caramel
    {
    "Name":"Caramel",
    "Calories":250
    }
    GET .../extras/FindByName/invoke?Name=Chocolate
    {
    "Name":"Chocolate",
    "Calories":200
    }
    GET .../extras/FindByMaxCalories/invoke?Calories=100
    {
    "elements": [
    {
    "Name":"Fat-free milk",
    "Calories":25
    },
    {
    "Name":"Cinammon",
    "Calories":10
    }
    ]
    }

    I left out all of the hypermedia to make the above easier to read.

  • Naming

    by Richard Pawson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I agree, Adam, that e.g. '../rels/..-invocation' might have been better than '../rels/..-invoke' in that it might have caused fewer people to get the wrong idea about it (even though URLs are supposed to be obscure, not pretty). But I don't think it's now worth making a breaking change to the spec for that now.

  • Re: No, RO is not an RPC system

    by Roberto Calero,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Nope, that's not REST. It's MVC'ish to the best but no REST at all.

    ~/objects/customers/31/actions/lastOrder/invoke => MVC'ish

    Before arguing anything else... what's the 1st class citizen object for the above? Customer or Order?

    Assuming it's Order then the url should be

    ~/objects/customers/31/lastOrder

    which effectively identifies the last order for customer = 31. The resource as such is uniquely identified. You can apply a POST, PUT, GET etc to the above and it'll be the actual operation (not the url) the one providing the context.

    ~/x/y/action/sub-action/etc are MVC standards in the other hand used to identify which controller/action/etc is running a given piece of logic. MVC is not REST of course.

  • REST is nothing to do with pretty URLs

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I'm afraid I don't follow your argument, here, Robert. You seem to be arguing that the format of the URL is important in order to claim RESTfulness. But REST has nothing to say about URL formats; REST is not about "pretty URLs".

    But if you did want a URL to be surfaced that looked similar to ~/objects/customers/31/lastOrder, you could model this responsibility (of a Customer knowing how to obtain its last Order) as a property rather than an action. In this case its URL would be ~/objects/customers/31/properties/lastOrder rather than ~/objects/customers/31/actions/lastOrder.

    The consequence of modelling things this way is that the property would be eagerly evaluated (when returning the representation of the customer) rather than lazily evaluated (when invoking the action).

  • The Restful Objects spec is not based on MVC

    by Richard Pawson,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Just to add to Dan's comments, Robert, the Restful Objects spec is not based on the MVC pattern - it makes no assumptions about the architecture of the server that implements the API. In the URL:

    ~/objects/customers/31/actions/lastOrder/invoke

    the 'actions/lastOrder' is not specifying a controller action, it is specifying an action (i.e. a method) on a domain object (customers/31).

    As it happens, the 'Restful Objects for .NET' implementation of the standard, as described in the article, does make use of ASP.NET MVC (in order to access the Web API framework), but it has just a single controller with a handful of generic methods - not a method for each of the actions that the domain model provides as you are inferring. The Restful Objects for Isis implementation is not, I think based on an MVC framework (though I'm not familiar with its internals and Dan might correct me on that).

  • Re: The Restful Objects spec is not based on MVC

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The Restful Objects for Isis implementation is not, I think based on an MVC framework (though I'm not familiar with its internals and Dan might correct me on that).


    You are correct: RO on Isis uses a JSR-311 framework (JBoss RestEasy).

  • Re: The Restful Objects spec is not based on MVC

    by Roberto Calero,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Just to add to Dan's comments, Robert, the Restful Objects spec is not based on the MVC pattern - it makes no assumptions about the architecture of the server that implements the API.


    Nobody has argued otherwise.


    In the URL:

    ~/objects/customers/31/actions/lastOrder/invoke

    the 'actions/lastOrder' is not specifying a controller action, it is specifying an action (i.e. a method) on a domain object (customers/31).


    There is not such a thing (in REST) like an action on a domain object. Furthermore, REST does not make any reference to "domain objects" but "resources" and the URL (actually URI) is the identifier for such resource. A REST operation (i.e. GET, POST, OPTIONS, etc) is performed on an URI and it's the operation the one providing context to it and not the URI.

    In your example, ~/objects/customers/31/actions/lastOrder/invoke is MVC-ish (at best) since it makes a reference to a "hard-action" in the URI to provide context. Moreover, it IS NOT the identifier for the resource you're working on (LastOrder? customer?) since what you're identifying is the action (but again) not the resource. Identifying actions/operations is not REST.

    It's not a discussion of pretty urls but just abiding to the concept of resource which is pivotal for REST.

  • Restful Objects spec defines resources for domain objects and their members

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Trust us, we *do* understand that REST relates to resources and representations. Restful Objects provides an automatic binding of these to an underlying domain model. When Richard says ".../actions/lastOrder/invoke" specifies an action, it's just shorthand for saying that it is a resource which addresses the result of invoking the lastOrder action on the underlying domain object.

    Per 5.2.1.1 of Fielding's dissertation, "any information that can be named can be a resource [such as] a temporal service (e.g. "today's weather in Los Angeles"). Our action resources are exactly the same thing.

    Adam Howard made the observation that we ought to have used "/invocation" in the URL rather than "/invoke". We agree with that; it might have prevented some confusion.

    With respect to "~/objects/customers/31/actions/lastOrder/invoke" having a reference to a "hard-action" to provide context, that isn't true. The context comes from the representation from which this link was obtained (and the "rel" of that link). The fact that "lastOrder" is part of URL is convenient for those who might want to build clients using templated URLs rather than using HATEOAS, but one can also write clients that strictly follow HATEOAS and treat the URLs as entirely opaque.

  • Re: Restful Objects spec defines resources for domain objects and their mem

    by Roberto Calero,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Trust us, we *do* understand that REST relates to resources and representations.


    I trust specs :-) RFC's are very trust-able. Humans sometimes aren't.

    Restful Objects provides an automatic binding of these to an underlying domain model. When Richard says ".../actions/lastOrder/invoke" specifies an action, it's just shorthand for saying that it is a resource which addresses the result of invoking the lastOrder action on the underlying domain object.


    That's cool for your framework and the compromises you've made for it. My discussion is not about your framework in specific but REST as purely described in the spec.

    Per 5.2.1.1 of Fielding's dissertation, "any information that can be named can be a resource [such as] a temporal service (e.g. "today's weather in Los Angeles"). Our action resources are exactly the same thing.


    Some agree, some do not.

    Adam Howard made the observation that we ought to have used "/invocation" in the URL rather than "/invoke". We agree with that; it might have prevented some confusion.


    Semantics really.

    With respect to "~/objects/customers/31/actions/lastOrder/invoke" having a reference to a "hard-action" to provide context, that isn't true. The context comes from the representation from which this link was obtained (and the "rel" of that link). The fact that "lastOrder" is part of URL is convenient for those who might want to build clients using templated URLs rather than using HATEOAS, but one can also write clients that strictly follow HATEOAS and treat the URLs as entirely opaque.


    IF the context comes from the representation or the "rel" of the link then you have a situation where your above uri just becomes inconsistent and confusing. .../invoke with OPTIONS? That'd be plain confusing. Using templated urls is just an implementation issue and URL's indeed should be opaque. In the above url, what's .../invoke doing? updating the last order? retrieving it? deleting it? Even if you change "invoke" by "invocation" the situation does not get any clearer and that's just a result of trying to make the url to identify the operation rather than the resource.

  • Re: Restful Objects spec defines resources for domain objects and their mem

    by Dan Haywood,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    you have a situation where your uri ["~/objects/customers/31/actions/lastOrder/invoke"] just becomes inconsistent and confusing. .../invoke with OPTIONS? That'd be plain confusing


    I did consider using OPTIONS on "~/objects/customers/31/actions/lastOrder" as a way of obtaining the action "prompt" representation, such that GET/PUT/POST could be used against that same URI in order to invoke the action...

    Even if you change "invoke" by "invocation" the situation does not get any clearer and that's just a result of trying to make the url to identify the operation rather than the resource.


    ... but it would seem that your point isn't specifically to do with how the RO spec defines its bindings from the domain model to RESTful resources, but rather the more fundamental question that as to whether an operation/action can be made available as a resource.

    On that, I don't think we're ever likely to agree. As is clear from the article, RO came out of the naked objects movement, a principle being its support for behaviourally-complete objects, rather than simple CRUD systems. The key to that is exposing domain object behaviour through actions.

    But I do thank you for your comments here. I'll also look into OPTIONS again. The RO spec is v1.0, but we will continue to evolve it based on feedback from implementors, users and from commentators such as yourself.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT