This
page
is
part
of
the
FHIR
Specification
(v5.0.0:
R5
-
STU
v6.0.0-ballot2:
Release
6
Ballot
(2nd
Draft)
(see
Ballot
Notes
).
This
is
the
The
current
published
version
in
it's
permanent
home
(it
will
always
be
available
at
this
URL).
is
5.0.0
.
For
a
full
list
of
available
versions,
see
the
Directory
of
published
versions
FHIR
Infrastructure
Work
Group
|
Maturity Level : N/A | Standards Status : Informative |
This page covers the workflows involved with the various 'search' mechanisms defined for use in FHIR. While the specific URL syntax varies for each of the different query options and, occasionally, the syntax of the response changes, the basics of the workflow is the same regardless of the search mechanism. There are two options: synchronous and asynchronous.
The synchronous search flow is similar to that in basic FHIR REST operations. The main difference with search is the introduction of paging to allow large result sets to be retrieved in reasonable-sized chunks.
1. The data consumer uses either a GET - where the search URL defines exactly what retrieval is to be invoked, along with any filters; or with POST - in which case the parameters are passed in the body of the HTTP call. The filters may also include desired page size. The contents of the URL vary by search mechanism, as will the format of response. Some of the search mechanisms may limit to only using GET or POST. The details will be discussed for each approach below.
2.
The
search
response
comes
back
in
the
body
of
the
HTTP
response.
For
most
search
mechanisms,
this
will
be
a
search-set
Bundle
containing
the
results
of
the
search.
If
no
results
are
found,
the
result
set
will
be
empty,
and
the
HTTP
response
will
still
be
200.
If
the
payload
is
a
search-set,
the
Bundle.total
will
be
set
to
0.
If
there
was
a
problem
with
the
format
of
the
search,
with
permissions
or
some
other
error,
an
appropriate
HTTP
code
will
be
raised
and
optionally
an
OperationOutcome
will
be
provided.
The
search
response
will
also
typically
include
links
that
allow
navigation
of
the
result
set.
For
search-set
Bundles,
these
will
be
the
'next',
'previous',
'first'
and
'last'
URLs
conveyed
in
Bundle.link
.
(Note
that
only
relevant
links
will
be
provided
and
not
all
servers
will
support
all
link
types
-
next
and
previous
are
commonly
supported;
first
and
last,
less
so.)
3. If navigation links were provided, this optional process allows the data consumer to navigate through the pages of the result set. Each new response will include links to navigate from that page.
Asynchronous search is identical to RESTful and operation asynchronous flows. Not all search approaches will support the asynchronous mechanism (this will be noted below in the section on each approach). Also, not all data sources will support the asynchronous mode, even if it is allowed. In an asynchronous request, there is no paging - all information is included in the file(s) produced by the asynchronous request
Step
1:
The
invocation
of
the
operation
asynchronously
is
identical
to
synchronous
search
invocation,
with
the
exception
that
the
Prefer
header
is
set
to
"respond-async".
(Note
that
the
server
is
not
obligated
to
respect
the
client's
stated
preference
-
it
could
still
respond
synchronously.).
The
response
includes
a
location-header
that
identifies
where
to
monitor
for
the
progress
of
the
asynchronous
operation.
Step 2: The data consumer polls the location specified in step 1 to see if the search is complete. So long as it is not, it gets back a 202 Accepted HTTP response, possibly with a message indicating the degree of progress. (Note: At any point, the data consumer could also cancel the request.)
Step 3: Once the search is complete, the response to the data consumer 's polling request changes to a 200 and conveys other information, including URLs to the location of the file (or files) that contain the results of the operation.
Step 4: The data consumer retrieves the identified file or files from the data source , containing the search response.
In
addition
to
the
instructions
on
asynchronous
exchange
in
the
base
spec,
asynchronous
search
is
described
in
more
detail
in
the
Bulk
Data
implementation
guide.
Implementers
considering
asynchronous
communication
should
be
familiar
with
this
guide,
as
the
capabilities
it
requires
are
much
more
likely
to
be
widely
implemented.
Details about workflow differences for each of the search mechanisms are listed below.
A
history
search
is
always
invoked
using
GET.
It
can
use
[base]/_history
,
[base]/[ResourceType]/_history
or
[base]/[resourceType]/[id]/_history
,
depending
on
whether
the
desired
history
is
for
the
whole
server,
a
particular
resource
type
or
for
a
single
resource
instance.
A
limited
set
of
parameters
are
permitted
to
filter
the
set
of
history
entries
provided
and
to
control
the
syntax
of
the
response.
The
response
is
always
a
Bundle
of
type
history
.
Paging
is
supported.
A
RESTful
search
can
be
invoked
using
GET
or
POST.
In
the
latter
case,
the
parameters
are
generally
sent
in
the
body
as
application/x-www-form-urlencoded
content.
However,
a
mixture
where
some
parameters
are
on
the
POST
URL
and
others
are
in
the
body
is
permitted.
The
base
URL
for
the
HTTP
call
can
be
either
[base]
or
[base]/[ResourceType]
or
[base]/[resourceType]/[id]/_history
depending
on
whether
the
search
is
across
multiple
resource
types
or
within
a
single
resource.
HL7
defines
an
extensive
set
of
search
parameters
to
both
filter
and
extend
the
output.
Additional
filtering
search
parameters
can
also
be
defined
by
implementers
or
other
specifications.
The
response
is
always
a
Bundle
of
type
search-set
.
Paging
is
supported.
A _filter search is identical to a regular RESTful search . The only difference is that one of the search parameters included (in the URL or body) is _filter.
GraphQL
works
similarly
to
RESTful
search
,
but
the
syntax
is
different.
Both
GET
and
POST
are
permitted.
For
both
GET
and
POST,
the
GraphQL
JSON
query
string
can
be
sent
as
a
parameter
in
the
query
URL.
With
POST,
it
can
also
be
sent
in
the
body,
with
the
ContentType
set
to
application/graphql
.
When
using
GraphQL,
parameters
must
be
exclusively
sent
in
either
the
URL
or
the
body
-
they
are
not
permitted
to
appear
in
both
locations.
The
base
URL
for
the
HTTP
call
can
be
one
of
[base]/$graphql
,
[base]/[ResourceType]/[id]/$graphql
or
[base]/.../$[operationName]?[parameters]&graphql=...
.
The
first
allows
a
search
against
the
whole
repository.
The
second
starts
the
search
with
a
specific
resource
instance.
The
last
allows
GraphQL
to
execute
against
the
results
returned
by
the
successful
invocation
of
the
operation
-
be
it
a
resource,
a
Parameters
instance
or
a
search-set
Bundle.
The
operation
itself
could
be
one
executed
at
the
base,
type,
or
instance
level.
The response to the search will be custom JSON - defined by the query itself. It can include full-blown resource structures, individual data elements or a combination of both. However, because it is not guaranteed to be FHIR-valid, it is not possible to invoke GraphQL as part of a batch.
If the Connection approach is used, then paging is possible. Asynchronous behavior is supported as it is for any FHIR operation .
There
is
not
a
formal
mechanism
for
using
CQL
to
perform
search
defined
in
the
core
FHIR
specification.
However,
the
draft
version
of
the
Clinical
Quality
Framework
(CQF)
IG
defines
a
couple
of
operations
allowing
data
to
be
retrieved
by
executing
arbitrary
CQL.
There
are
two
options.
The
cpg-cql
operation
executes
CQL
passed
directly
as
an
argument.
The
cpg-library-evaluate
operation
executes
CQL
specified
in
a
referenced
library.
The
cpg-cql
operation
is
invoked
at
the
base
URL
(
[base]/$cql
.
It
can
potentially
be
invoked
using
GET
if
it
does
not
use
the
parameters
parameter
but
can
also
use
POST.
The
cpg-library-evaluate
operation
is
invoked
with
the
URL
[base]/Library/[id]/$evaluate
can
be
invoked
using
GET
provided
that
the
parameters
parameter
is
not
used.
It
can
also
be
invoked
with
POST
(with
parameters
past
using
a
Parameters
instance).
Neither
supports
paging
as
the
results
aren't
expected
to
come
back
in
a
search-set
Bundle
.
Asynchronous
execution
is
possible
as
for
any
FHIR
operation
.
There
is
no
FHIR-specific
mechanism
for
invoking
a
SPARQL
query.
The
W3C
defines
a
few
ways
to
invoke
a
SPARQL
query
using
a
RESTful
interface.
These
mechanisms
correspond
to
the
standard
GET/POST
query
flows
used
for
FHIR-defined
queries.
Other
invocation
mechanisms
are
also
possible,
including
the
potential
use
of
a
FHIR
operation.
(No
standard
operation
has
yet
been
defined.)
Because
FHIR
search-set
Bundles
are
not
involved,
there
is
no
query
continuation
mechanism.
It
is
possible
that
the
FHIR
async
mechanism
could
be
used
when
invoking
SPARQL,
but
if
so,
this
would
be
a
custom
behavior
outside
the
scope
of
FHIR
-
as
SPARQL
invocation
itself
is
outside
the
scope
of
FHIR.
The
_query
mechanism
works
in
a
similar
manner
to
RESTful
search
.
It
can
be
invoked
either
at
the
[base]?_query=name
or
[base]/[resourceType]?_query=name
level.
Depending
on
the
nature
of
the
parameters
defined
by
the
named
operation,
it
may
be
possible
to
invoke
it
using
GET.
It
can
always
be
invoked
using
POST
-
where
the
body
is
a
Parameters
instance.
The
response
(if
successful)
is
a
search-set
Bundle
.
That
bundle
may
include
links
that
support
paging.
Asynchronous
invocation
is
supported.