Burke, as I have written the code, it would work exactly like that.

@Roger, can you add the next couple steps to this story, where we get into
a scenario that my code shouldn't be able to handle?

-Darius

On Wed, Apr 25, 2012 at 2:08 PM, Burke Mamlin <bmam...@regenstrief.org>wrote:

> Ok, so if I want to create a drug order and a referral order for patient
> with uuid 123-456, then request all orders for the patient, it would look
> something like this (simplifying the order details for a simpler example)?
>
> *1. Create a drug order for my patient; they're built-in:*
> POST order
> { "patient":"123-456", "type":"drugorder", "order":"penicillin 500 mg
> orally twice daily for 2 weeks" }
>
> *2. Install a module to add support for referral orders:*
> Install a referrals module that adds a referralorder type of order.
>  Presumably, by introducing a new concept class for referral order, along
> with a handler for the new order type and, of course, a ReferralOrder class
> that extends Order.
>
> *3. Create a referral order for my patient:*
> POST order
> { "patient":"123-456", "type":"referralorder", "order":"cardiology
> referral please evaluate for rheumatic heart disease" }
>
> *4. Find all the active orders for my patient:*
> GET order?patient=123-456
> [
> { "patient":"123-456", "type":"drugorder", "order":"penicillin 500 mg
> orally twice daily for 2 weeks", "uri":"…" },
> { "patient":"123-456", "type":"referralorder", "order":"cardiology
> referral please evaluate for rheumatic heart disease", "uri":"…" }
> ]
>
> Is that close?
>
> -Burke
>
> On Tue, Apr 24, 2012 at 9:21 PM, Darius Jazayeri 
> <djazayeri+...@gmail.com>wrote:
>
>> On RESTWS-243 <https://tickets.openmrs.org/browse/RESTWS-243> I've
>> attached a patch that contains my implementation that I'm now ready to
>> commit. (It's what Roger was responding to in his email.)
>>
>> I'm going to hold off on committing until after tomorrow's design call in
>> case we have time to discuss this a bit.
>>
>> Basically what I've done is allow resources to indicate that they support
>> subclasses, and if they do, they'll have all appropriate
>> DelegatingSubclassHandlers registered with them via spring.
>>
>> The idea is that we're hiding subclasses from the consumer of the REST
>> API. As far as they're concerned there is a single "order" resource, which
>> has documents of different types (e.g. "order", "drugorder", etc.) Behind
>> the scenes each type is a subclass, but in REST that's not visible, rather
>> they're exposed as different document types.
>>
>> DelegatingSubclassHandler encapsulates the methods subclasses need to
>> specify for their owning resource.
>>
>> Here is the functionality that my approach supports:
>>
>> *GET order*
>>
>>    - gets all orders regardless of type
>>    - each document in the list may have different types
>>    - the top-level resource does the db query and delegates to the
>>    appropriate handler to convert each result
>>
>> *GET order?t=drugorder*
>>
>>    - gets all orders whose type is drugorder
>>    - the subclass handler does the db query
>>    - In my implementation GET order?t=order (i.e. get only things that
>>    are order stubs) is not allowed
>>
>> *GET order?patient=<uuid>*
>>
>>    - gets all orders for the given patient
>>    - each document in the list may have different types
>>
>> *GET order?patient=<uuid>&t=drugorder*
>>
>>    - gets all orders for the given patient whose type is drugorder
>>    - if the subclass handler defines a suitable method, we use it,
>>    otherwise the top-level resource queries by patient, and manually filters
>>    out by type
>>
>> *GET order/<uuid>*
>>
>>    - returns a specific order
>>    - representations are defined by the type, e.g. { "type":
>>    "drugorder", "dose": "100", ... }
>>
>> *POST order*
>>
>>    - creates a new order
>>    - you must specify the type in the content, e.g. { "type":
>>    "drugorder", "dose": "100", ... }
>>    - allowed properties are defined by the type
>>
>> *POST order/<uuid>*
>>
>>    - modifies an existing order
>>    - you are not allowed to change the type
>>    - allowed properties are defined by the type
>>
>> *DELETE order/<uuid>*
>>
>>    - voids an order
>>    - handled by the top-level resource, not the subclass handler
>>
>> *DELETE order/<uuid>?purge=true*
>>
>>    - purges an order
>>    - handled by the top-level resource, not the subclass handler
>>
>> @Roger, can you please phrase your counterproposal in terms of the
>> additional functionality that you want to expose beyond these methods?
>>
>> -Darius
>>
>>
>> On Mon, Apr 23, 2012 at 9:54 AM, Burke Mamlin <bmam...@regenstrief.org>wrote:
>>
>>> Roger,
>>>
>>> Could you provide some concrete examples?
>>>
>>> -Burke
>>>
>>>
>>> On Mon, Apr 23, 2012 at 8:07 AM, Friedman, Roger (CDC/CGH/DGHA) (CTR) <
>>> r...@cdc.gov> wrote:
>>>
>>>>  AN ALTERNATIVE APPROACH TO SUBCLASS IMPLEMENTATION****
>>>>
>>>> In this approach, subclass resources remain resources, just are mapped
>>>> via the superclass. Substantially all operations are delegated to the
>>>> appropriate subclass resource. This is motivated by simplicity, validation
>>>> and representation considerations. It is also motivated by a privilege
>>>> issue I just realized – the people authorized to create/update a lab order
>>>> are likely different from those allowed to create/update a drug order. I
>>>> have assumed that the privilege of updating a parent class field in
>>>> subclass record requires only parent class privileges****
>>>>
>>>> I don't believe this alternative requires much in the way of changes to
>>>> existing code other than mappings; adding the controller and resource for
>>>> each superclass; some changes in asRepresentation where it finds the right
>>>> representation to use; and some changes where updates are going on to allow
>>>> the possibility that the fields to be looked for in the request body may
>>>> come from an object which is a parent class of the object being updated. It
>>>> eliminates the need for the two variable lists used by Darius (although
>>>> they could still be used if it was thought they added value). I still think
>>>> it is a good idea to treat ActiveLists as an abstract class so that the
>>>> AllergyList and the ProblemList appear to be two different superclasses.
>>>> ****
>>>>
>>>> All members of a class hierarchy request a mapping to
>>>> /<superclass>?t=<subclass>. The superclass also requests a mapping to
>>>> /<superclass>?!t. I have tried to make all the calls of /<superclass>?!t
>>>> work the same as calls to /<superclass>?t=<superclass>, if I have missed
>>>> please let me know.  It might be worthwhile to extend Resource to
>>>> SuperclassResource to make the coding of the type-free calls easier.  All
>>>> representations include a t virtual field which contains the actual
>>>> subclass of the object being represented.****
>>>>
>>>> 1. GET <superclass>?t=<subclass>&v=<rep>, GET <superclass>?!t****
>>>>
>>>> Purpose is to get all records of a particular subclass in a formatted
>>>> representation. Spring routes this to the subclass controller. The subclass
>>>> resource uses getAll to get a (polymorphic) list of objects.
>>>> asRepresentation determines the class of each object and looks for the
>>>> requested representation in that subclass resource; if it exists, it is
>>>> used; if not, the parent class resource (if any) is searched for a
>>>> representation; this continues until the t subclass has been searched, at
>>>> which point a rep does not exist error is thrown.****
>>>>
>>>> 2. GET <superclass>?t=<subclass>&v=<rep>&q=<search param>, GET
>>>> <superclass>?!t&v=<rep>&q=<search param>****
>>>>
>>>> Purpose is to use the standard query for a subclass to get a formatted
>>>> representation. Spring routes this to the subclass controller. The subclass
>>>> resource uses doSearch to get a (polymorphic) list of objects.
>>>> asRepresentation determines the class of each object and looks for the
>>>> requested representation in that subclass resource; if it exists, it is
>>>> used; if not, the parent class resource (if any) is searched for a
>>>> representation; this continues until the t subclass has been searched, at
>>>> which point a rep does not exist error is thrown.****
>>>>
>>>> 3. GET <superclass>?t=<subclass>&v=<rep>&<custom search>=<search param>
>>>> ****
>>>>
>>>> Purpose is to do a custom search that is defined at some level of the
>>>> class hierarchy.  Spring routes this to the subclass controller. The
>>>> subclass controller creates a resource for its type and delegates the
>>>> search to it. The resource uses service methods to do the search to produce
>>>> a (polymorphic) list of objects. asRepresentation determines the class of
>>>> each object and looks for the requested representation in that subclass
>>>> resource; if it exists, it is used; if not, the parent class resource (if
>>>> any) is searched for a representation; this continues until the t subclass
>>>> has been searched, at which point a rep does not exist error is thrown.
>>>> ****
>>>>
>>>> 4. GET <superclass>/<uuid>?!t&v=<rep>****
>>>>
>>>> Purpose is to get all records of a particular subclass in a formatted
>>>> representation. Spring routes this to the superclass controller. The
>>>> superclass resource uses getByUuid to get an object. asRepresentation
>>>> determines the class of each object and looks for the requested
>>>> representation in that subclass resource; if it exists, it is used; if not,
>>>> the parent class resource (if any) is searched for a representation; this
>>>> continues until the t subclass has been searched, at which point a rep does
>>>> not exist error is thrown.****
>>>>
>>>> 5. GET <superclass>/<uuid>?t=<subclass>&v=<rep>****
>>>>
>>>> Purpose is to use a representation from a parent class. Like 5, except
>>>> after getting by Uuid, the subclass resource coerces the result to be its
>>>> type. asRepresentation determines the class of each object and looks for
>>>> the requested representation in that subclass resource; if it exists, it is
>>>> used; if not, the parent class resource (if any) is searched for a
>>>> representation; this continues until the supertype has been searched, at
>>>> which point a rep does not exist error is thrown.****
>>>>
>>>> 6. POST <superclass>?t=<subclass> {body}
>>>>
>>>> Purpose is to create a new object of type <subclass>. The subclass
>>>> resource creates a new object whose fields are extracted from the body (no
>>>> need to know. The subclass resource save method uses services method to
>>>> save the object; validation takes place in the save method.
>>>>
>>>> 7. POST <superclass>/<uuid>?!t {body}****
>>>>
>>>> Purpose is to update an object of any subclass. The type is determined
>>>> and the operation is delegated to the resource of the actual type.****
>>>>
>>>> 8. POST <superclass/<uuid>?t=<subclass> {body}****
>>>>
>>>> Purpose is to update an object using only parent-level fields. This is
>>>> to avoid additional privileges at the actual subclass level. The type is
>>>> deermined and the operation is delegated to the resource of the declared
>>>> type. Throws an error if the actual type is not a subclass of the type
>>>> declared. ****
>>>>
>>>> 9. DELETE <superclass>/<uuid>?!t&!purge, DELETE
>>>> <superclass>/<uuid>?t=<subclass>&!purge****
>>>>
>>>> Purpose is to delete an object of any subclass. The type is determined
>>>> and the operation is delegated to the resource of the actual type. The
>>>> subclass, if present, must match the actual type of the resource.****
>>>>
>>>> 10. DELETE <superclass>/<uuid>?purge&!t, DELETE
>>>> <superclass>/<uuid>?purge****
>>>>
>>>> Purpose is to purge an object of any subclass. The type is determine
>>>> and the operation is delegated to the resource of the actual type. The
>>>> subclass, if present, must match the actual type of the resource.****
>>>>  ------------------------------
>>>> Click here to 
>>>> unsubscribe<lists...@listserv.iupui.edu?body=SIGNOFF%20openmrs-devel-l>from
>>>>  OpenMRS Developers' mailing list
>>>
>>>
>>> ------------------------------
>>> Click here to 
>>> unsubscribe<lists...@listserv.iupui.edu?body=SIGNOFF%20openmrs-devel-l>from 
>>> OpenMRS Developers' mailing list
>>>
>>
>> ------------------------------
>> Click here to 
>> unsubscribe<lists...@listserv.iupui.edu?body=SIGNOFF%20openmrs-devel-l>from 
>> OpenMRS Developers' mailing list
>>
>
> ------------------------------
> Click here to 
> unsubscribe<lists...@listserv.iupui.edu?body=SIGNOFF%20openmrs-devel-l>from 
> OpenMRS Developers' mailing list
>

_________________________________________

To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to 
lists...@listserv.iupui.edu with "SIGNOFF openmrs-devel-l" in the  body (not 
the subject) of your e-mail.

[mailto:lists...@listserv.iupui.edu?body=SIGNOFF%20openmrs-devel-l]

Reply via email to