The question of the day is: Should there be one resource (Task) or two (ActionRequest/ActionResponse)?
I've been a proponent of the one resource approach, but will certainly acknowledge the value of a request/response approach as well. I think though, the real question is not about resources per se, but rather about functionality. Today, FHIR is mostly about describing a set of common behaviors (CRUD) around resources, with a little functionality beyond storage and search.
Workflow is about the execution (behavior) of activities. The kinds of behavior that need to be effected can be seen in the list of WS Human Task Event Types and Data. That list describes the activities involved in workflow management: Management of the task, changing task states, assignment of tasks, capture of task related data, et cetera.
In an object oriented model, these events are the operations that can be performed on a task. In FHIR, these could be treated as operations on a Task resource that made appropriate changes to the resource, or responded with error messages when those changes could not be made due to required behaviors of the object. These operations are where we get into a "Request/Response model". The operation is the request, and the updates to the Task resource, or the error raised in response to the request is the response.
There are a number of different ways to deal with workflow. As I've previously mentioned, there are different models for collaboration on workflows, notably around the differences between orchestration and choreography. I like the discussion in the previous link about Orchestration being intra-institutional vs. choreography being inter-institutional. I think it helps to narrow the discussion a bit.
As a resource, Task serves to record the status and progress of a workflow, but does not imply a specific workflow structure or rules around how it might be choreographed or orchestrated. If multiple organizations are able to create and update task resource, that would enable choreography. Task operations could effect request/response behavior patterns to support enforcement of a limited set of allowed task state changes and workflow controls (e.g., per WS Human Task requirements), but still enable either kind of workflow. Implementation Guides on the use of the Task resource would assist in defining specific institutional or orchestrated workflows in a more refined way.
The only net benefit I see behind the request/response resource pattern is that of supporting separate maintenance of resources, such that the initiator of a workflow can create and maintain the request resource, and the responder can create and maintain the response resource. But frankly, I don't see a lot of value in that because there's never a single resource that tells you what the state of the task is at any point in time. Instead, you must look at a sequence of requests and responses, and manage the state yourself. I know that's a bad idea. Anytime you have multiple systems implementing complex logic like that, you'll have multiple systems looking at sequences, and come, based on their interpretation of how workflow is supposed to work, different opinions about what the state of the system is. It is much better to say "this is the state of the system", and allow the maintainer of that state (resource) to impose rules on how it might be changed if it feels a need to, or alternatively, allow it to be completely ignorant of any transition rules.
We don't have to choose between choreography and orchestration, and we don't need to choose between a task resource or request/response patterns. We can simply say: Here is the resource. Here are operations that work in this way on the resource. And a system can say: I implement this resource, and I implement these operations, and you get both.
I've been a proponent of the one resource approach, but will certainly acknowledge the value of a request/response approach as well. I think though, the real question is not about resources per se, but rather about functionality. Today, FHIR is mostly about describing a set of common behaviors (CRUD) around resources, with a little functionality beyond storage and search.
Workflow is about the execution (behavior) of activities. The kinds of behavior that need to be effected can be seen in the list of WS Human Task Event Types and Data. That list describes the activities involved in workflow management: Management of the task, changing task states, assignment of tasks, capture of task related data, et cetera.
In an object oriented model, these events are the operations that can be performed on a task. In FHIR, these could be treated as operations on a Task resource that made appropriate changes to the resource, or responded with error messages when those changes could not be made due to required behaviors of the object. These operations are where we get into a "Request/Response model". The operation is the request, and the updates to the Task resource, or the error raised in response to the request is the response.
There are a number of different ways to deal with workflow. As I've previously mentioned, there are different models for collaboration on workflows, notably around the differences between orchestration and choreography. I like the discussion in the previous link about Orchestration being intra-institutional vs. choreography being inter-institutional. I think it helps to narrow the discussion a bit.
As a resource, Task serves to record the status and progress of a workflow, but does not imply a specific workflow structure or rules around how it might be choreographed or orchestrated. If multiple organizations are able to create and update task resource, that would enable choreography. Task operations could effect request/response behavior patterns to support enforcement of a limited set of allowed task state changes and workflow controls (e.g., per WS Human Task requirements), but still enable either kind of workflow. Implementation Guides on the use of the Task resource would assist in defining specific institutional or orchestrated workflows in a more refined way.
The only net benefit I see behind the request/response resource pattern is that of supporting separate maintenance of resources, such that the initiator of a workflow can create and maintain the request resource, and the responder can create and maintain the response resource. But frankly, I don't see a lot of value in that because there's never a single resource that tells you what the state of the task is at any point in time. Instead, you must look at a sequence of requests and responses, and manage the state yourself. I know that's a bad idea. Anytime you have multiple systems implementing complex logic like that, you'll have multiple systems looking at sequences, and come, based on their interpretation of how workflow is supposed to work, different opinions about what the state of the system is. It is much better to say "this is the state of the system", and allow the maintainer of that state (resource) to impose rules on how it might be changed if it feels a need to, or alternatively, allow it to be completely ignorant of any transition rules.
We don't have to choose between choreography and orchestration, and we don't need to choose between a task resource or request/response patterns. We can simply say: Here is the resource. Here are operations that work in this way on the resource. And a system can say: I implement this resource, and I implement these operations, and you get both.
The notion of using an operation to request a change to the status of a task seems to presume synchronous behavior. That won't necessarily be the case. At the moment, when an Order resources is posted, the OrderResponse won't necessarily show up for minutes or even hours. It would be really useful to see an example of the following scenario: Placer asks for fulfillment of Order A by Filler 1. Filler 1 refuses. Placer asks for fulfillment of Order A by Filler 2. Filler 2 accepts. Filler 2 provides preliminary results (linked to the fulfillment request). Filler 2 provides final results (linked to the fulfillment request) and indicates that they're done. Filler 2 provides amended results (linked to the fulfillment request). What does that look like in a Task-based implementation? How many tasks? Who owns which ones? How is the overall state derived?
ReplyDelete