Retrieving and Posting Data
Frontend modules interact with the OpenMRS server via the APIs exposed by its modules. In general, most of the endpoints we use are provided by the FHIR Module (opens in a new tab). Most of the rest are provided by the REST Module (opens in a new tab), which is documented here (opens in a new tab).
Endpoints from the FHIR Module should always be preferred, when they are available. FHIR is an interoperability standard which OpenMRS supports.
Some data is available using higher-level functions or custom React Hooks provided
by @openmrs/esm-framework
. These should be used when available.
All of this functionality (React hooks excepted) is provided by the
@openmrs/esm-api
(opens in a new tab)
package, which is part of @openmrs/esm-framework
.
The React hooks are in
@openmrs/esm-react-utils
(opens in a new tab),
which is also part of @openmrs/esm-framework
. See the
API Docs (opens in a new tab).
FHIR
To use the FHIR API, we recommend using SWR (opens in a new tab) based hooks and the openmrsFetch
(opens in a new tab) fetcher function to retrieve data from the server. SWR offers a host of features that help us deliver an improved user experience.
Here's an example of using SWR to retrieve a patient from the FHIR API.
import useSWR from "swr";
import { fhirBaseUrl, openmrsFetch, fhir } from "@openmrs/esm-framework";
const { data, error, isLoading, mutate } = useSWR<fhir.Patient, Error>(
`${fhirBaseUrl}/Patient/${patientUuid}`,
openmrsFetch
);
If you have questions about FHIR support in OpenMRS, you can ask in the FHIR Squad Slack channel (opens in a new tab).
Other OpenMRS server APIs
Some administrative endpoints will likely never have a proper representation in FHIR (e.g., endpoints for managing encounter types). When no suitable FHIR endpoint is available, you will want to use a different OpenMRS server API. The REST Web Services API (opens in a new tab) is used widely across many of our frontend modules.
Here's an example of a custom SWR hook that retrieves visits data.
import useSWR from "swr";
import { openmrsFetch, Visit } from "@openmrs/esm-framework";
interface VisitData {
results: Array<Visit>;
}
/* Custom data fetching hook */
export function useVisits() {
const url = `/ws/rest/v1/visit?includeInactive=false`;
const { data, error, isLoading, mutate } = useSWR<{ data: VisitData }, Error>(url, openmrsFetch);
return {
visits: data,
isLoading,
error,
mutate,
};
}
We can leverage this useVisits
hook in our visits
component as follows:
const Visits = () => {
const { visits, isError, isLoading } = useVisits();
if (isLoading) {
return <DataTableSkeleton role="progressbar" />
}
if (error) {
// render error state
}
if (visits?.length) {
// render visits
}
return (
// render empty state
)
}
export default Visits;
The mutate
function returned by useSWR
can be used to update the cache and trigger a re-render of the component. This is useful when we want to update the UI after a successful mutation.
const res = await saveVisitNote(payload);
try {
if (res.status === 201) {
mutate();
closeWorkspace();
// show success toast
}
} catch (error) {
// handle error
}
Posting data to the server
Here's an example that demonstrates posting session data to the server.
import { openmrsFetch } from "@openmrs/esm-framework";
const abortController = new AbortController();
abortController.abort();
openmrsFetch("/ws/rest/v1/session", {
method: "POST",
body: {
username: "hi",
password: "there",
},
signal: abortController.signal,
});
It is best practice for POST requests to have an
AbortController (opens in a new tab).
You should ensure that AbortController.abort()
is called when the component is unmounted
if the request is not yet completed.
In a React Component this is usually accomplished by making the request
in a useEffect
hook (opens in a new tab):
useEffect(() => {
const abortController = new AbortController();
someFetchFunction(abortController).then(setResult).catch(setError);
return () => abortController.abort();
}, []);
API Objects
Some API objects are made available via React hooks (or via framework-agnostic subscriptions).
The hooks are in
@openmrs/esm-react-utils
,
and the subscription-yielding equivalents are in
@openmrs/esm-api
(opens in a new tab).
See for example useVisitTypes
(opens in a new tab)
and the corresponding getVisitTypes
(opens in a new tab).