extension-operationdefinition-allowed-type
Introduction
Scope and Usage
The OperationDefinition resource provides a formal computable definition of an operation or a named query. The OperationDefinition serves two principal purposes:
- To allow for automatic determination of system compatibility
- To allow for dynamic generation of forms to drive the operations
See below for further information about these, and about how operations and named queries are executed.
Boundaries and Relationships
OperationDefinitions are published to define operations that servers can implement in a common fashion. The FHIR specification itself describes some (see below), and other organizations (including IHE, national programs, jurisdictions and vendors) are able to publish additional OperationDefinitions.
OperationDefinition resources are referred to from two different places:
- From a CapabilityStatement, to declare what operations a system does or should implement
- From another OperationDefinition resource. This allows for a server to describe a limited implementation of a standard operation, or to allow traceability if the server has to rename the operation due to a name clash
OperationDefinitions can be used to define a custom query (kind = query, discussed below) which functions as a special kind of search. This is different to a SearchParameter because a custom query may define multiple parameters and can define of complex search behavior beyond what SearchParameter can specify. It also typically overrides the behavior of the query functionality, while search parameters can only act as additional filters.
Notes
Derived OperationDefinitions
OperationDefinitions can describe entirely new operations, but they can also describe a restricted implementation of an existing operation, e.g. when a server implements some but not all the features of an operation defined in another specification. These are called derived operation definitions.
An OperationDefinition does by declaring a base as shown in the example:
{ "resourceType" : "OperationDefinition", "id" : "example", "url" : "http://hl7.org/fhir/OperationDefinition/example", "name" : "PopulateQuestionnaire", // snip "code" : "populate", "base" : "http://hl7.org/fhir/OperationDefinition/Questionnaire-populate" // snip }
When constraining an existing operation like this, operation definitions can make optional parameters required or not used, introduce new parameters (required or optional), clarify documentation, and even change the code for the operation (see next section). The derived operation can't change the nature of the operation itself, nor can it change add types to parameters or prohibit mandatory parameters.
When deriving from another operation, the following rules SHOULD be followed. Note that these rules are asserted as SHOULD rather than SHALL only because they were introduced after the resource became normative. Systems that fail to follow these rules are likely to result in unsafe interoperability.
- SHOULD NOT change the value of
affectsStatefrom the original OperationDefinition - SHOULD have the same
kindas the original OperationDefinition - SHOULD have the same
experimentalas the original OperationDefinition - SHOULD have a
resourcethat is equivalent to or a subset of the original OperationDefinitiontarget - SHOULD NOT set
system,type, orinstanceto 'true' if they were false in the original OperationDefinition - if the original
inputProfileis valued, SHOULD have aninputProfilevalued such that:- the
inputProfileis the same as, is a profile of, or imposes the originalinputProfile, or - the
inputProfileis otherwise compatible with the originalinputProfile(all parameters profiled with min cardinality 1 from the originalinputProfileare profiled; all parameters profiled in the originalinputProfileare profiled with equivalent or tighter constraints)
- the
- if the original
outputProfileis valued, SHOULD have anoutputProfilevalued such that:- the outputProfile is the same as, is a profile of, or imposes the original outputProfile, or
- the outputProfile is otherwise compatible with the original outputProfile (all parameters profiled with min cardinality 1 from the original outputProfile are profiled; all parameters profiled in the original outputProfile are profiled with equivalent or tighter constraints)
- SHOULD have a
parameterwith the samenameas anyparameterof the original OperationDefinition that has aparameter.minvalue of greater than zero - for any
parameterwith the sameparameter.nameas aparameterof the original OperationDefinition,- SHOULD have the same
useas the originalparameter - SHOULD have the same or greater
minvalue as the originalparameter - SHOULD have the same or lesser
maxvalue as the originalparameter - if the original
parameter.typeis valued, SHOULD have the sametypeas the originalparameter - if the original
parameter.allowedTypeis valued, SHOULD have anallowedTypethat is the same or a subset of the originalparameter.allowedType - if the original
parameter.targetProfileis valued, SHOULD only includetargetProfilethat are the same as, or profiles of, originalparameter.targetProfileentries. It is also possible to reduce the number of allowed targetProfiles. - if the original
parameter.searchTypeis valued, SHOULD have asearchTypewith the same value as the originalparameter.searchType - if the original
parameter.bindingis valued, SHOULD have abindingwith the same values as, or values meeting the constraints of, the originalparameter.binding - if the original
parameter.referencedFromis valued, SHOULD have areferencedFromwith the same values. - if the original
parameter.partis valued,- SHOULD have a
partwith the samenameas anypartof the original OperationDefinition with aminvalue of greater than zero - for any
partwith the samenameas apartof the original OperationDefinition, SHOULD meet the above derivation rules
- SHOULD have a
- SHOULD have the same
- If parameters are removed, the interpretation is that those parameters SHOULD be ignored, not that they are erroneous to include. Note that unexpected parameters SHOULD generally be ignored by implementations.
- Additional optional parameters not present in the base observation MAY be added.
- Such parameters SHOULD be safe to ignore if the operation is invoked on a system that only supports the base definition.
- It is discouraged to introduce parameters with the same name as a parameter that was removed as part of a higher-level derivation. Behavior in this situation is undefined.
Request for ballot feedback: We would like the 'SHOULD' assertions above to become 'SHALL' assertions. We are invoking our usual implementer outreach process to find out whether anyone else objects, but please file tickets for any rules you do not believe can be enforced that way.
OperationDefinition Code
Operations are invoked by their code, not their name. The name is descriptive, for code generation, e.g. ValueSetExpansion, while the code is what is used in a URL e.g. http://example.org/fhir/ValueSet/$expand. When defining operations, for maximum compatibility, use only lowercase ASCII characters. See Naming Rules & Guidelines for the internal HL7 rules around codes, which are useful additional advice for all implementers.
It is possible for two different organizations to create different operation definitions with the same code or, perhaps more likely, to define equivalent operations that have the same code but incompatible approaches in their parameter lists. Note that HL7 will never define multiple operations with the same code.
It is also possible, though unlikely, that a server will be required to support both of these operations. If this is the case, the server is able to do this by giving one of them a new code and referring to it by definition in the capability statement. To illustrate this, assume that two different organizations, "orgA" and "orgB", both define an operation with a code dothis, and the definitions are incompatible. OrgA publishes its operation definition at http://orga.com/fhir/dothis.xml, and OrgB publishes its operation at http://fhir.orgb.com/meta/OperationDefinition/dothis. The server is able to implement both. Its capability statement will say:
<CapabilityStatement xmlns="http://hl7.org/fhir">
<rest>
<operation>
<name value="dothis"/>
<definition>
<reference value="http://orga.com/fhir/dothis.xml"/>
</definition>
</operation>
<operation>
<name value="dothis2"/>
<definition>
<reference value="http://fhir.orgb.com/meta/OperationDefinition/dothis"/>
</definition>
</operation>
<!-- snip -->
</rest>
</CapabilityStatement>
If a general purpose cross server client is looking for the implementation of the http://fhir.orgb.com/meta/OperationDefinition/dothis operation and wants to be robust against this name clash problem, instead of simply executing the $dothis operation, it can look at the server's CapabilityStatement for the underlying definition URI and then execute with the name given in the capability statement.
Note to implementers: it would be more consistent if CapabilityStatement.rest.operation.name was actually called "code", since it relates to OperationDefinition.code, but the confusion this can cause wasn't appreciated until the resource was normative.
Describing Operation Parameters
There are 2 ways to describe the input and output parameters for an operation:
- Using
OperationDefinition.parameterto describe the parameters - Using
OperationDefinition.inputProfileandOperationDefinition.outputProfile
The parameters is a simple list of possible parameters, along with cardinalities and types. The profiles allow a more complete set of validation rules to be provided, such as constraints, additional bindings etc., and to provide a richer set of documentation (examples, mappings, etc.). OperationDefinitions SHALL always define the parameters using OperationDefinition.parameter in the resource, and MAY also provide profiles for the parameters. If present, the profiles SHALL NOT disagree with the parameters defined for the operation.
As an example, consider an operation that defines 3 parameters, 2 in and 1 out:
| In Parameters: |
|---|
| Name |
| a |
| An integer parameter |
| | b | 0..1 | Patient | | |
A patient parameter
| | Out Parameters: | | Name | Cardinality | Type | Binding | Profile | Documentation | | c | 1..1 | decimal | | |
A result parameter
|
In addition to specifying the operation parameters directly, an operation definition can also provide a profile:
"inputProfile" : "http://example.org/StructureDefinition/op.x.in.profile"
This profile would describe a parameters resource with 2 parameters (using slicing), with the same details as the table above. The operation definition would still list the parameters directly to save applications consuming the definition (e.g. to produce an OpenAPI document) from parsing and interpreting the profile.
When profiles are used, they SHALL be profiles on the Parameter resource (even if the expectation is that parameters will often be sent as part of the URL). The elements must be aligned as follows:
- Parameters SHOULD be listed in the same order
- The number of input and output parameters must be the same
- The parameter names must be the same (parameter.name SHALL be the fixed value for the `parameter.name` in the profile and SHOULD be the same as the parameter slice name)
- The parameter.min and max SHALL be the same as the min and max for the corresponding parameter slice.
- If the parameter has a type and no list of allowed types, then the profile on parameter slice value SHALL either have the same type, or be one or more types that are derived from that type.
- If the parameter has a list of allowed types, then then the types of the corresponding parameter slice value SHALL correspond such that every allowed type is either listed explicitly as an allowed type or there are one or more types listed that derive from the operation parameter type. There SHALL NOT be any types listed in the profile for 'value' that do not correspond to a type in the parameter
- All targetProfiles listed on the OperationDefinition for the parameter SHALL match targetProfiles for at least one of the types for the value element in the corresponding parameter slice and there SHALL NOT be any targetProfiles listed that are not matched in the OperationDefinition parameter.
- The binding in the profile SHALL either be the same, or provide more constraints. The profile may also have additionalBindings.
- Best practice is that the parameter definition only captures
requiredbindings; other binding strengths SHOULD be captured in the profile - The .documentation SHOULD be the same as the .definition for the parameter slice
- If there are child parameters, then there SHALL be aligned 'part' slices within the parameter following the same rules as above
Executing Operations
OperationDefinitions with kind = operation are executed as defined in the Operations Framework.
Executing Named Queries
Named queries (OperationDefinitions with kind = query) are executed by performing a search with the value of the search parameter "_query" set to the name provided in the definition. Named queries are a kind of search: both client and server must conform to all the requirements of search, including regarding the content of the result bundle. From a client's perspective, it's really just a kind of search, though it may have a completely separate processing pipeline. Named queries cannot be invoked using the $[operationname] mechanism.
If the named query is to be performed over the RESTful API, all the parameters must be simple search parameters, so that they can be represented directly in the URL without tricky encoding issues. Named queries always have a single output parameter named "result" of type Bundle.
The order of parameters doesn't matter; a _query parameter anywhere in the query means the entire query will be handled according to the named query OperationDefinition. Parameters may repeat if permitted by the OperationDefinition (or for unlisted common search parameters, as specified in this specification).
For named queries, all the standard search parameters are automatically in scope. Specifically, all common search parameters (e.g. _id, _text, _count, _sort, etc.) as well as search parameters that pertain to the resources returned by the operation (e.g. name for Patient or Organization) are allowed. "In scope" doesn't mean all servers will support them. If a server wishes to declare which search parameters it supports for a given named query, it must explicitly list these in its OperationDefinition (which might be a server-specific derived OperationDefinition).
Passing Resources to Operations
There are two ways to pass resources to an operation: directly or by reference. The definition of an operation distinguishes between these two, since they have very different behaviors and consequences.
As an example, take the ValueSet.$expand operation. This operation takes a ValueSet as a direct parameter. The type of the parameter is defined as 'ValueSet'. In a Parameters resource, it would be represented like this:
<parameter> <name value="valueset"/> <resource> <ValueSet>
</ValueSet>
</resource>
</parameter>
or, in JSON:
"parameter": [ { "name": "valueset", "resource": { "resourceType": "ValueSet", // ValueSet contents } } ]
Other parameters are passed by reference. For example, the PlanDefinition.$apply operation takes more than one parameters of type Reference - subject, encounter and organization. The expectation is that the server performing the operation will resolve those references as part of the operation execution. In a parameters resource, the subject parameter would be represented like this:
<parameter> <name value="subject"/> <valueReference> <reference value="Patient/123"/> </valueReference> </parameter>
or, in JSON:
"parameter": [ { "name": "subject", "valueReference" : { "reference" : "Patient/123" } } ]
Some operations can take either form; in that case, two distinct parameters must be defined: one for a resource as a direct parameter, and one for a reference.
Determining System Compatibility
A client can determine the compatibility of the server by processing its capability statement and ensuring that the server implements the specific operation definitions and parameters required by the client. The client can then report a useful error to the user rather than allowing mystifying operational errors to occur.
However, there are fundamental limitations to this approach because there are many aspects of these operations that are not (or cannot be) defined in a formal fashion using OperationDefinition, for example, co-occurrence constraints among parameters.
In the same sense, a 3rd party tool can examine a server's CapabilityStatement and a client's definition of an acceptable server to determine whether those two system are interoperable or not.
Dynamically Generating Forms
Finally, it is possible to generate user interface forms automatically from the OperationDefinition. The documentation in the OperationDefinition.description and OperationDefinition.parameter.documentation should be sufficient to allow moderately technical users to guess at the correct content of the form. For this reason, highly technical documentation should go in OperationDefinition.comment.
It is anticipated that this would be used to automate development processes, rather than to generate end-user forms: such users will usually need more support than can be offered in a generated form.
Operations defined as part of this Specification
<%operationslist%>
StructureDefinition
Elements (Simplified)
- Extension [0..*]: - Which types are allowed for a parameter, when the base type is Abstract
- Extension.extension [-..0]: -
- Extension.url [-..-]: -
- Extension.value[x] [1..-]: uri
Mappings
- extension-operationdefinition-allowed-type Mappings — 0 mapping entries
Mapping Exceptions
operationdefinition-definition-mapping-exceptions.xml
Divergent Elements
- Definition.url → OperationDefinition.url
- commentsUnmatched | reason=Unknown | pattern=Can be a
urn:uuid:or aurn:oid:but realhttp/s:addresses are preferred. Multiple instances may share the same URL if they have a distinct version.
- commentsUnmatched | reason=Unknown | pattern=Can be a
The determination of when to create a new version of a resource (same url, new version) vs. defining a new artifact is up to the author. Considerations for making this decision are found in Technical and Business Versions.
In some cases, the resource can no longer be found at the stated url, but the url itself cannot change. Implementations can use the meta.source element to indicate where the current master source of the resource can be found. | resource=Can be a urn:uuid: or a urn:oid: but real http: addresses are preferred. Multiple instances may share the same URL if they have a distinct version.
The determination of when to create a new version of a resource (same url, new version) vs. defining a new artifact is up to the author. Considerations for making this decision are found in Technical and Business Versions.
In some cases, the resource can no longer be found at the stated url, but the url itself cannot change. Implementations can use the meta.source element to indicate where the current master source of the resource can be found.
- Definition.name → OperationDefinition.name
- requirementsUnmatched | reason=Unknown | pattern=Supports code generation. | resource=Support code generation.
- Definition.derivedFromCanonical → OperationDefinition.base
- missingTypes | reason=Unknown | pattern=canonical(Definition)
- extraTypes | reason=Unknown
- shortUnmatched | reason=Unknown | pattern=Based on FHIR protocol or definition | resource=Marks this as a profile of the base
- definitionUnmatched | reason=Unknown | pattern=The canonical URL pointing to another FHIR-defined protocol, guideline, orderset or other definition that is adhered to in whole or in part by this definition. | resource=Indicates that this operation definition is a constraining profile on the base.
- requirementsUnmatched | reason=Unknown | pattern=Protocols and order sets may be refinements of more generic protocols and order sets.
- Definition.description → OperationDefinition.description
- summary | reason=Resource wasn't in summary when it went normative | pattern=true
- commentsUnmatched | reason=Added additional resource-specific context | pattern=This description can be used to capture details such as comments about misuse, instructions for clinical use and interpretation, literature references, examples from the paper world, etc. It is not a rendering of the operation definition as conveyed in the 'text' field of the resource itself. This item SHOULD be populated unless the information is available from context. | resource=This description can be used to capture details such as comments about misuse, instructions for clinical use and interpretation, literature references, examples from the paper world, etc. It is not a rendering of the operation definition as conveyed in the 'text' field of the resource itself. This item SHOULD be populated unless the information is available from context (e.g. the language of the operation definition is presumed to be the predominant language in the place the operation definition was created).
- Definition.useContext → OperationDefinition.useContext
- definitionUnmatched | reason=Unknown | pattern=The content was developed with a focus and intent of supporting the contexts that are listed. These contexts may be general categories (gender, age, ...) or may be references to specific programs (insurance plans, studies, ...) and may be used to assist with indexing and searching for appropriate operation definitions. | resource=The content was developed with a focus and intent of supporting the contexts that are listed. These contexts may be general categories (gender, age, ...) or may be references to specific programs (insurance plans, studies, ...) and may be used to assist with indexing and searching for appropriate operation definition.
- Definition.jurisdiction → OperationDefinition.jurisdiction
- shortUnmatched | reason=Unknown | pattern=Intended jurisdiction for operation definition (if applicable) | resource=Jurisdiction of the authority that maintains the operation definition (if applicable)
- definitionUnmatched | reason=Unknown | pattern=A legal or geographic region in which the operation definition is intended to be used. | resource=A legal or geographic region in which the authority that maintains the resource is operating. In general, the jurisdiction is also found in the useContext. The useContext may reference additional jurisdictions because the defining jurisdiction does not necessarily limit the jurisdictions of use.
- commentsUnmatched | reason=Unknown | pattern=It may be possible for the operation definition to be used in jurisdictions other than those for which it was originally designed or intended
DEPRECATION NOTE: For consistency, implementations are encouraged to migrate to using the new 'jurisdiction' code in the useContext element. (I.e. useContext.code indicating http://terminology.hl7.org/CodeSystem/usage-context-type#jurisdiction and useContext.valueCodeableConcept indicating the jurisdiction.). | resource=It may be possible for the operation definition to be used in jurisdictions other than those for which it was originally designed or intended.
DEPRECATION NOTE: For consistency, implementations are encouraged to migrate to using the new 'jurisdiction' code in the useContext element. (I.e. useContext.code indicating http://terminology.hl7.org/CodeSystem/usage-context-type#jurisdiction and useContext.valueCodeableConcept indicating the jurisdiction.)
- Definition.code → OperationDefinition.code
- missingTypes | reason=Unknown | pattern=CodeableConcept
- extraTypes | reason=Unknown
- shortUnmatched | reason=Unknown | pattern=Service to be done | resource=Recommended name for operation in search url
- definitionUnmatched | reason=Unknown | pattern=A code that identifies the specific service or action that was or is being performed. | resource=The label that is recommended to be used in the URL for this operation. In some cases, servers may need to use a different CapabilityStatement operation.name to differentiate between multiple SearchParameters that happen to have the same code.
Unmapped Elements
- Definition.approvalDate — Unknown
- Definition.effectivePeriod — Unknown
- Definition.product — Not relevant for this resource
- Definition.lastReviewDate — Unknown
- Definition.subject — Unknown
- Definition.identifier — Not relevant for this resource
- Definition.derivedFromUri — Not relevant for this resource
- Definition.performerType — Not relevant for this resource
- Definition.partOf — Not relevant for this resource
- Definition.topic — Unknown
operationdefinition-fivews-mapping-exceptions.xml
Unmapped Elements
- FiveWs.what — Not relevant for this resource
- FiveWs.author — Not relevant for this resource
- FiveWs.actor — Not relevant for this resource
- FiveWs.cause — Not relevant for this resource
- FiveWs.where — Not relevant for this resource
- FiveWs.context — Not relevant for this resource
- FiveWs.init — Not relevant for this resource
- FiveWs.source — Not relevant for this resource
- FiveWs.who — Not relevant for this resource
- FiveWs.grade — Not relevant for this resource
- FiveWs.planned — Not relevant for this resource
- FiveWs.done — Not relevant for this resource
- FiveWs.subject — Not relevant for this resource