[jboss-as7-dev] Detyped and REST configuration API

David M. Lloyd david.lloyd at redhat.com
Tue Nov 30 11:05:14 EST 2010


On 11/30/2010 12:03 AM, Brian Stansberry wrote:
> On 11/29/10 10:18 PM, David M. Lloyd wrote:
>> On 11/29/2010 05:15 PM, Brian Stansberry wrote:
>>> Updates via differencing:
>>>
>>> A model update consists of a client sending a detyped representation of
>>> a part of the model. The update will include all of that portion of the
>>> model; both modified and unmodified properties. The server compares that
>>> detyped representation to the current state of the model and generates
>>> the AbstractModelUpdate objects needed to bring the model up to the
>>> desired state.
>>
>> I don't know if I agree with this approach.  This means that to do an
>> update you have to do a read-modify-write, so there's a race condition.
>
> In most cases there's inherently a race condition. The user has some
> idea of the state of the system which may be outdated, and then tries to
> perform an update. In a REST system this is handled with ETag headers
> and IF-Match headers.

Good point; however what I'm saying is if your update targets just one 
field on an element, then you can be guaranteed that you aren't going to 
reset some other field to an old value, so the problem just disappears 
(at least, on the assumption that the user doesn't care what the old 
value was, that just want to change it to some new value; we could take 
it to an extreme and have a CAS type update but... meh).

>>     In addition, there are many update types which require simultaneous
>> updating of fields which means that there is a larger class of invalid
>> inputs which would need specialized error messages such as "if you
>> update field blah, you also have to update field bzzt" and so forth.
>
> How is that avoidable with a detyped API? On the client side you have no
> update class to enforce preconditions.

My point being that if we use dedicated update objects (as opposed to 
generic model updates), we can perform more "regular" validation on the 
update object itself (i.e. these fields are required, these are 
optional) which means no specialized error messages, just generic 
"missing required field foo" kinds of things.

>> I'll grant that many of our updates are adds and removes.  But sometimes
>> the address would be unknown until the add is complete (deployments for
>> example); I think this general scenario (system-generated addresses) is
>> perfectly valid.
>>
>
> That's a typical REST scenario; you add a new child to a parent resource
> and you get back the URL of that child, which tells you its id. That
> doesn't seem like a hard thing.

True.

>> And don't forget that some of our updates will be related to a model
>> element but won't actually *update* that model element.  For example,
>> "interrupt thread #5 from the pool defined by
>> domain/subsystem/threads/pools/fred".  Or it might even be something
>> like "interrupt thread #1234 via domain/subsystems/threads"; it might
>> not relate to that specific an element.  Perhaps the updates themselves
>> should be the combination of an update identifier with the address of
>> any thing(s) being modified in the payload of the update itself.
 >
> Good; the topic of this thread was "configuration API" but bringing in
> discussion of non-configuration management operations is a good thing.
> Management operations always seemed more RPC-ish and less RESTful.
>
> In general, my concern about the approach you're outlining is it feels
> RPCish and not RESTful. I'm actually more comfortable with RPC, but we
> have a requirement to provide a REST interface and I'm concerned about
> straying so far from REST principles that the REST interface becomes an
> unmaintainable hack.

I'm not worried about that.  We can support GET for reading (of course), 
PUT for adding (in SOME cases), LIST for certain read tasks, DELETE for 
removal (in SOME cases), and POST for nontrivial updates.  It's 
REST-enough for me.

>> Another prime example would be deployment.  A deployment plan contains
>> model information (i.e. the deployment name and content) as well as
>> non-model information (i.e. the plan itself).  It wouldn't be good to
>> try to cram this into a pseudo-update of some sort of virtual fields or
>> something.
>
> I see a deployment plan (or any updates that want deployment-plan-like
> behavior) as being a resource that gets created, manipulated and then
> can be referred back to (e.g. to obtain results).

In the REST API, sure.  However I think that this should be encapsulated 
in a single object in the untyped API - the REST server can take care of 
maintaining the state necessary to assemble the plan.

In this way, an address is NOT constrained to just the single model. 
Which is true anyway - an address has to not only represent a position 
in the domain model, but also in the host models within the domain, and 
the server models within the hosts.  It stands to reason that the REST 
API should also be able to access other, intermediate structures as well.

>> In other words I might ask for all deployments in server group X, and
>> I'd get back a list of fully addressed model elements.  Or I might ask
>> for a specific configuration of a connector in a profile and get back
>> just that connector, but fully addressed - it wouldn't be rooted in the
>> domain.
>
> Or you might ask for all the subsystems in a profile, but not want the
> full details; just their "ids". Granted, that could be handled as a
> separate query, a sort of "getChildIds()" instead of "getChildren()".
> For reads I saw an id-only element as a placeholder for children, not
> for uninteresting parents. As you say, there is no need for
> uninteresting parents; that's what the address is for.

Well I think a REST-y "LIST" operation makes sense for this; return a 
list of addresses and there you go.  In the API itself we could have a 
generic list operation which operates on mappy and listy things.

> For writes, the complex update case I describe above can handled by
> making the client provide multiple targetted updates (add extension, add
> thread pool, add socket binding, add subsystem) wrapped in an atomic
> update plan.

That seems reasonable.  That would just be a list of other updates I guess.

-- 
- DML



More information about the jboss-as7-dev mailing list