001/*-
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.repository;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.i18n.Msg;
024import ca.uhn.fhir.model.api.IQueryParameterType;
025import ca.uhn.fhir.rest.api.MethodOutcome;
026import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
027import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException;
028import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
029import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
030import com.google.common.annotations.Beta;
031import org.hl7.fhir.instance.model.api.IBaseBundle;
032import org.hl7.fhir.instance.model.api.IBaseConformance;
033import org.hl7.fhir.instance.model.api.IBaseParameters;
034import org.hl7.fhir.instance.model.api.IBaseResource;
035import org.hl7.fhir.instance.model.api.IIdType;
036
037import java.util.Collections;
038import java.util.List;
039import java.util.Map;
040
041/**
042 * <p>
043 * This API is under-going active development, so it should be considered beta-level.
044 * </p>
045 *
046 * <p>
047 * This interface is a Java rendition of the FHIR REST API. All FHIR operations are defined at the
048 * HTTP level, which is convenient from the specification point-of-view since FHIR is built on top
049 * of web standards. This does mean that a few HTTP specific considerations, such as transmitting
050 * side-band information through the HTTP headers, bleeds into this API.
051 * </p>
052 *
053 * <p>
054 * One particularly odd case are FHIR Bundle links. The specification describes these as opaque to
055 * the end-user, so a given FHIR repository implementation must be able to resolve those directly.
056 * See {@link Repository#link(Class, String)}
057 * </p>
058 *
059 * <p>
060 * This interface also chooses to ignore return headers for most cases, preferring to return the
061 * Java objects directly. In cases where this is not possible, or the additional headers are crucial
062 * information, HAPI's {@link MethodOutcome} is used.
063 * </p>
064 *
065 * <p>
066 * Implementations of this interface should prefer to throw the exceptions derived from
067 * {@link ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException}
068 *
069 * All operations may throw {@link AuthenticationException}, {@link ForbiddenOperationException}, or
070 * {@link InternalErrorException} in addition to operation-specific exceptions.
071 * </p>
072 *
073 * <p>
074 * If a given operation is not supported, implementations should throw an
075 * {@link NotImplementedOperationException}. The capabilities operation, if supported, should return
076 * the set of supported interactions. If capabilities is not supported, the components in this
077 * repository will try to invoke operations with "sensible" defaults. For example, by using the
078 * standard FHIR search parameters. Discussion is on-going to determine what a "sensible" minimal
079 * level of support for interactions should be.
080 * </p>
081 *
082 * @see <a href="https://www.hl7.org/fhir/http.html">FHIR REST API</a>
083 */
084@Beta
085public interface Repository {
086
087        // CRUD starts here
088
089        /**
090         * Reads a resource from the repository
091         *
092         * @see <a href="https://www.hl7.org/fhir/http.html#read">FHIR read</a>
093         * @see <a href="https://www.hl7.org/fhir/http.html#vread">FHIR vRead</a>
094         *
095         * @param <T> a Resource type
096         * @param <I> an Id type
097         * @param resourceType the class of the Resource type to read
098         * @param id the id of the Resource to read
099         * @return the Resource
100         */
101        default <T extends IBaseResource, I extends IIdType> T read(Class<T> resourceType, I id) {
102                return this.read(resourceType, id, Collections.emptyMap());
103        }
104
105        /**
106         * Reads a Resource from the repository
107         *
108         * @see <a href="https://www.hl7.org/fhir/http.html#read">FHIR read</a>
109         * @see <a href="https://www.hl7.org/fhir/http.html#vread">FHIR vRead</a>
110         *
111         * @param <T> a Resource type
112         * @param <I> an Id type
113         * @param resourceType the class of the Resource type to read
114         * @param id the id of the Resource to read
115         * @param headers headers for this request, typically key-value pairs of HTTP headers
116         * @return the Resource
117         */
118        <T extends IBaseResource, I extends IIdType> T read(Class<T> resourceType, I id, Map<String, String> headers);
119
120        /**
121         * Creates a Resource in the repository
122         *
123         * @see <a href="https://www.hl7.org/fhir/http.html#create">FHIR create</a>
124         *
125         * @param <T> a Resource type
126         * @param resource the Resource to create
127         * @return a MethodOutcome with the id of the created Resource
128         */
129        default <T extends IBaseResource> MethodOutcome create(T resource) {
130                return this.create(resource, Collections.emptyMap());
131        }
132
133        /**
134         * Creates a Resource in the repository
135         *
136         * @see <a href="https://www.hl7.org/fhir/http.html#create">FHIR create</a>
137         *
138         * @param <T> a Resource type
139         * @param resource the Resource to create
140         * @param headers headers for this request, typically key-value pairs of HTTP headers
141         * @return a MethodOutcome with the id of the created Resource
142         */
143        <T extends IBaseResource> MethodOutcome create(T resource, Map<String, String> headers);
144
145        /**
146         * Patches a Resource in the repository
147         *
148         * @see <a href="https://www.hl7.org/fhir/http.html#patch">FHIR patch</a>
149         *
150         * @param <I> an Id type
151         * @param <P> a Parameters type
152         * @param id the id of the Resource to patch
153         * @param patchParameters parameters describing the patches to apply
154         * @return a MethodOutcome with the id of the patched resource
155         */
156        default <I extends IIdType, P extends IBaseParameters> MethodOutcome patch(I id, P patchParameters) {
157                return this.patch(id, patchParameters, Collections.emptyMap());
158        }
159
160        /**
161         * Patches a Resource in the repository
162         *
163         * @see <a href="https://www.hl7.org/fhir/http.html#patch">FHIR patch</a>
164         *
165         * @param <I> an Id type
166         * @param <P> a Parameters type
167         * @param id the id of the Resource to patch
168         * @param patchParameters parameters describing the patches to apply
169         * @param headers headers for this request, typically key-value pairs of HTTP headers
170         * @return a MethodOutcome with the id of the patched resource
171         */
172        default <I extends IIdType, P extends IBaseParameters> MethodOutcome patch(
173                        I id, P patchParameters, Map<String, String> headers) {
174                return throwNotImplementedOperationException("patch is not supported by this repository");
175        }
176
177        /**
178         * Updates a Resource in the repository
179         *
180         * @see <a href="https://www.hl7.org/fhir/http.html#update">FHIR update</a>
181         *
182         * @param <T> a Resource type
183         * @param resource the Resource to update
184         * @return a MethodOutcome with the id of the updated Resource
185         */
186        default <T extends IBaseResource> MethodOutcome update(T resource) {
187                return this.update(resource, Collections.emptyMap());
188        }
189
190        /**
191         * Updates a Resource in the repository
192         *
193         * @see <a href="https://www.hl7.org/fhir/http.html#update">FHIR update</a>
194         *
195         * @param <T> a Resource type
196         * @param resource the Resource to update
197         * @param headers headers for this request, typically key-value pairs of HTTP headers
198         * @return a MethodOutcome with the id of the updated Resource
199         */
200        <T extends IBaseResource> MethodOutcome update(T resource, Map<String, String> headers);
201
202        /**
203         * Deletes a Resource in the repository
204         *
205         * @see <a href="https://www.hl7.org/fhir/http.html#delete">FHIR delete</a>
206         *
207         * @param <T> a Resource type
208         * @param <I> an Id type
209         * @param resourceType the class of the Resource type to delete
210         * @param id the id of the Resource to delete
211         * @return a MethodOutcome with the id of the deleted resource
212         */
213        default <T extends IBaseResource, I extends IIdType> MethodOutcome delete(Class<T> resourceType, I id) {
214                return this.delete(resourceType, id, Collections.emptyMap());
215        }
216
217        /**
218         * Deletes a Resource in the repository
219         *
220         * @see <a href="https://www.hl7.org/fhir/http.html#delete">FHIR delete</a>
221         *
222         * @param <T> a Resource type
223         * @param <I> an Id type
224         * @param resourceType the class of the Resource type to delete
225         * @param id the id of the Resource to delete
226         * @param headers headers for this request, typically key-value pairs of HTTP headers
227         * @return a MethodOutcome with the id of the deleted resource
228         */
229        <T extends IBaseResource, I extends IIdType> MethodOutcome delete(
230                        Class<T> resourceType, I id, Map<String, String> headers);
231
232        // Querying starts here
233
234        /**
235         * Searches this repository
236         *
237         * @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a>
238         *
239         * @param <B> a Bundle type
240         * @param <T> a Resource type
241         * @param bundleType the class of the Bundle type to return
242         * @param resourceType the class of the Resource type to search
243         * @param searchParameters the searchParameters for this search
244         * @return a Bundle with the results of the search
245         */
246        default <B extends IBaseBundle, T extends IBaseResource> B search(
247                        Class<B> bundleType, Class<T> resourceType, Map<String, List<IQueryParameterType>> searchParameters) {
248                return this.search(bundleType, resourceType, searchParameters, Collections.emptyMap());
249        }
250
251        /**
252         * Searches this repository
253         *
254         * @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a>
255         *
256         * @param <B> a Bundle type
257         * @param <T> a Resource type
258         * @param bundleType the class of the Bundle type to return
259         * @param resourceType the class of the Resource type to search
260         * @param searchParameters the searchParameters for this search
261         * @param headers headers for this request, typically key-value pairs of HTTP headers
262         * @return a Bundle with the results of the search
263         */
264        <B extends IBaseBundle, T extends IBaseResource> B search(
265                        Class<B> bundleType,
266                        Class<T> resourceType,
267                        Map<String, List<IQueryParameterType>> searchParameters,
268                        Map<String, String> headers);
269
270        // Paging starts here
271
272        /**
273         * Reads a Bundle from a link on this repository
274         *
275         * This is typically used for paging during searches
276         *
277         * @see <a href="https://www.hl7.org/fhir/bundle-definitions.html#Bundle.link">FHIR Bundle
278         *      link</a>
279         *
280         * @param <B> a Bundle type
281         * @param url the url of the Bundle to load
282         * @return a Bundle
283         */
284        default <B extends IBaseBundle> B link(Class<B> bundleType, String url) {
285                return this.link(bundleType, url, Collections.emptyMap());
286        }
287
288        /**
289         * Reads a Bundle from a link on this repository
290         *
291         * This is typically used for paging during searches
292         *
293         * @see <a href="https://www.hl7.org/fhir/bundle-definitions.html#Bundle.link">FHIR Bundle
294         *      link</a>
295         *
296         * @param <B> a Bundle type
297         * @param url the url of the Bundle to load
298         * @param headers headers for this request, typically key-value pairs of HTTP headers
299         * @return a Bundle
300         */
301        default <B extends IBaseBundle> B link(Class<B> bundleType, String url, Map<String, String> headers) {
302                return throwNotImplementedOperationException("link is not supported by this repository");
303        }
304
305        // Metadata starts here
306
307        /**
308         * Returns the CapabilityStatement/Conformance metadata for this repository
309         *
310         * @see <a href="https://www.hl7.org/fhir/http.html#capabilities">FHIR capabilities</a>
311         *
312         * @param <C> a CapabilityStatement/Conformance type
313         * @param resourceType the class of the CapabilityStatement/Conformance to return
314         * @return a CapabilityStatement/Conformance with the repository's metadata
315         */
316        default <C extends IBaseConformance> C capabilities(Class<C> resourceType) {
317                return this.capabilities(resourceType, Collections.emptyMap());
318        }
319
320        /**
321         * Returns the CapabilityStatement/Conformance metadata for this repository
322         *
323         * @see <a href="https://www.hl7.org/fhir/http.html#capabilities">FHIR capabilities</a>
324         *
325         * @param <C> a CapabilityStatement/Conformance type
326         * @param resourceType the class of the CapabilityStatement/Conformance to return
327         * @param headers headers for this request, typically key-value pairs of HTTP headers
328         * @return a CapabilityStatement/Conformance with the repository's metadata
329         */
330        default <C extends IBaseConformance> C capabilities(Class<C> resourceType, Map<String, String> headers) {
331                return throwNotImplementedOperationException("capabilities is not supported by this repository");
332        }
333
334        // Transactions starts here
335
336        /**
337         * Performs a transaction or batch on this repository
338         *
339         * @see <a href="https://www.hl7.org/fhir/http.html#transaction">FHIR transaction</a>
340         *
341         * @param <B> a Bundle type
342         * @param transaction a Bundle with the transaction/batch
343         * @return a Bundle with the results of the transaction/batch
344         */
345        default <B extends IBaseBundle> B transaction(B transaction) {
346                return this.transaction(transaction, Collections.emptyMap());
347        }
348
349        /**
350         * Performs a transaction or batch on this repository
351         *
352         * @see <a href="https://www.hl7.org/fhir/http.html#transaction">FHIR transaction</a>
353         *
354         * @param <B> a Bundle type
355         * @param transaction a Bundle with the transaction/batch
356         * @param headers headers for this request, typically key-value pairs of HTTP headers
357         * @return a Bundle with the results of the transaction/batch
358         */
359        default <B extends IBaseBundle> B transaction(B transaction, Map<String, String> headers) {
360                return throwNotImplementedOperationException("transaction is not supported by this repository");
361        }
362
363        // Operations starts here
364
365        /**
366         * Invokes a server-level operation on this repository that returns a Resource
367         *
368         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
369         *
370         * @param <R> a Resource type to return
371         * @param <P> a Parameters type for operation parameters
372         * @param name the name of the operation to invoke
373         * @param parameters the operation parameters
374         * @param returnType the class of the Resource the operation returns
375         * @return the results of the operation
376         */
377        default <R extends IBaseResource, P extends IBaseParameters> R invoke(
378                        String name, P parameters, Class<R> returnType) {
379                return this.invoke(name, parameters, returnType, Collections.emptyMap());
380        }
381
382        /**
383         * Invokes a server-level operation on this repository that returns a Resource
384         *
385         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
386         *
387         * @param <R> a Resource type to return
388         * @param <P> a Parameters type for operation parameters
389         * @param name the name of the operation to invoke
390         * @param parameters the operation parameters
391         * @param returnType the class of the Resource the operation returns
392         * @param headers headers for this request, typically key-value pairs of HTTP headers
393         * @return the results of the operation
394         */
395        default <R extends IBaseResource, P extends IBaseParameters> R invoke(
396                        String name, P parameters, Class<R> returnType, Map<String, String> headers) {
397                return throwNotImplementedOperationException("server-level invoke is not supported by this repository");
398        }
399
400        /**
401         * Invokes a server-level operation on this repository
402         *
403         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
404         *
405         * @param <P> a Parameters type for operation parameters
406         * @param name the name of the operation to invoke
407         * @param parameters the operation parameters
408         * @return a MethodOutcome with a status code
409         */
410        default <P extends IBaseParameters> MethodOutcome invoke(String name, P parameters) {
411                return this.invoke(name, parameters, Collections.emptyMap());
412        }
413
414        /**
415         * Invokes a server-level operation on this repository
416         *
417         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
418         *
419         * @param <P> a Parameters type for operation parameters
420         * @param name the name of the operation to invoke
421         * @param parameters the operation parameters
422         * @param headers headers for this request, typically key-value pairs of HTTP headers
423         * @return a MethodOutcome with a status code
424         */
425        default <P extends IBaseParameters> MethodOutcome invoke(String name, P parameters, Map<String, String> headers) {
426                return throwNotImplementedOperationException("server-level invoke is not supported by this repository");
427        }
428
429        /**
430         * Invokes a type-level operation on this repository that returns a Resource
431         *
432         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
433         *
434         * @param <R> a Resource type to return
435         * @param <P> a Parameters type for operation parameters
436         * @param <T> a Resource type to do the invocation for
437         * @param resourceType the class of the Resource to do the invocation for
438         * @param name the name of the operation to invoke
439         * @param parameters the operation parameters
440         * @param returnType the class of the Resource the operation returns
441         * @return the results of the operation
442         */
443        default <R extends IBaseResource, P extends IBaseParameters, T extends IBaseResource> R invoke(
444                        Class<T> resourceType, String name, P parameters, Class<R> returnType) {
445                return this.invoke(resourceType, name, parameters, returnType, Collections.emptyMap());
446        }
447
448        /**
449         * Invokes a type-level operation on this repository that returns a Resource
450         *
451         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
452         *
453         * @param <R> a Resource type to return
454         * @param <P> a Parameters type for operation parameters
455         * @param <T> a Resource type to do the invocation for
456         * @param resourceType the class of the Resource to do the invocation for
457         * @param name the name of the operation to invoke
458         * @param parameters the operation parameters
459         * @param headers headers for this request, typically key-value pairs of HTTP headers
460         * @param returnType the class of the Resource the operation returns
461         * @return the results of the operation
462         */
463        <R extends IBaseResource, P extends IBaseParameters, T extends IBaseResource> R invoke(
464                        Class<T> resourceType, String name, P parameters, Class<R> returnType, Map<String, String> headers);
465
466        /**
467         * Invokes a type-level operation on this repository
468         *
469         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
470         *
471         * @param <P> a Parameters type for operation parameters
472         * @param <T> a Resource type to do the invocation for
473         * @param resourceType the class of the Resource to do the invocation for
474         * @param name the name of the operation to invoke
475         * @param parameters the operation parameters
476         * @return a MethodOutcome with a status code
477         */
478        default <P extends IBaseParameters, T extends IBaseResource> MethodOutcome invoke(
479                        Class<T> resourceType, String name, P parameters) {
480                return this.invoke(resourceType, name, parameters, Collections.emptyMap());
481        }
482
483        /**
484         * Invokes a type-level operation on this repository
485         *
486         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
487         *
488         * @param <P> a Parameters type for operation parameters
489         * @param <T> a Resource type to do the invocation for
490         * @param resourceType the class of the Resource to do the invocation for
491         * @param name the name of the operation to invoke
492         * @param parameters the operation parameters
493         * @param headers headers for this request, typically key-value pairs of HTTP headers
494         * @return a MethodOutcome with a status code
495         */
496        default <P extends IBaseParameters, T extends IBaseResource> MethodOutcome invoke(
497                        Class<T> resourceType, String name, P parameters, Map<String, String> headers) {
498                return throwNotImplementedOperationException("type-level invoke is not supported by this repository");
499        }
500
501        /**
502         * Invokes an instance-level operation on this repository that returns a Resource
503         *
504         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
505         *
506         * @param <R> a Resource type to return
507         * @param <P> a Parameters type for operation parameters
508         * @param <I> an Id type
509         * @param id the id of the Resource to do the invocation on
510         * @param name the name of the operation to invoke
511         * @param parameters the operation parameters
512         * @param returnType the class of the Resource the operation returns
513         * @return the results of the operation
514         */
515        default <R extends IBaseResource, P extends IBaseParameters, I extends IIdType> R invoke(
516                        I id, String name, P parameters, Class<R> returnType) {
517                return this.invoke(id, name, parameters, returnType, Collections.emptyMap());
518        }
519
520        /**
521         * Invokes an instance-level operation on this repository that returns a Resource
522         *
523         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
524         *
525         * @param <R> a Resource type to return
526         * @param <P> a Parameters type for operation parameters
527         * @param <I> an Id type
528         * @param id the id of the Resource to do the invocation on
529         * @param name the name of the operation to invoke
530         * @param parameters the operation parameters
531         * @param returnType the class of the Resource the operation returns
532         * @param headers headers for this request, typically key-value pairs of HTTP headers
533         * @return the results of the operation
534         */
535        <R extends IBaseResource, P extends IBaseParameters, I extends IIdType> R invoke(
536                        I id, String name, P parameters, Class<R> returnType, Map<String, String> headers);
537
538        /**
539         * Invokes an instance-level operation on this repository
540         *
541         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
542         *
543         * @param <P> a Parameters type for operation parameters
544         * @param <I> an Id type
545         * @param id the id of the Resource to do the invocation on
546         * @param name the name of the operation to invoke
547         * @param parameters the operation parameters
548         * @return a MethodOutcome with a status code
549         */
550        default <P extends IBaseParameters, I extends IIdType> MethodOutcome invoke(I id, String name, P parameters) {
551                return this.invoke(id, name, parameters, Collections.emptyMap());
552        }
553
554        /**
555         * Invokes an instance-level operation on this repository
556         *
557         * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a>
558         *
559         * @param <P> a Parameters type for operation parameters
560         * @param <I> an Id type
561         * @param id the id of the Resource to do the invocation on
562         * @param name the name of the operation to invoke
563         * @param parameters the operation parameters
564         * @param headers headers for this request, typically key-value pairs of HTTP headers
565         * @return a MethodOutcome with a status code
566         */
567        default <P extends IBaseParameters, I extends IIdType> MethodOutcome invoke(
568                        I id, String name, P parameters, Map<String, String> headers) {
569                return throwNotImplementedOperationException("instance-level invoke is not supported by this repository");
570        }
571
572        // History starts here
573
574        /**
575         * Returns a Bundle with server-level history for this repository
576         *
577         * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a>
578         *
579         * @param <B> a Bundle type to return
580         * @param <P> a Parameters type for input parameters
581         * @param parameters the parameters for this history interaction
582         * @param returnType the class of the Bundle type to return
583         * @return a Bundle with the server history
584         */
585        default <B extends IBaseBundle, P extends IBaseParameters> B history(P parameters, Class<B> returnType) {
586                return this.history(parameters, returnType, Collections.emptyMap());
587        }
588
589        /**
590         * Returns a Bundle with server-level history for this repository
591         *
592         * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a>
593         *
594         * @param <B> a Bundle type to return
595         * @param <P> a Parameters type for input parameters
596         * @param parameters the parameters for this history interaction
597         * @param returnType the class of the Bundle type to return
598         * @param headers headers for this request, typically key-value pairs of HTTP headers
599         * @return a Bundle with the server history
600         */
601        default <B extends IBaseBundle, P extends IBaseParameters> B history(
602                        P parameters, Class<B> returnType, Map<String, String> headers) {
603                return throwNotImplementedOperationException("server-level history is not supported by this repository");
604        }
605
606        /**
607         * Returns a Bundle with type-level history for this repository
608         *
609         * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a>
610         *
611         * @param <B> a Bundle type to return
612         * @param <P> a Parameters type for input parameters
613         * @param <T> a Resource type to produce history for
614         * @param resourceType the class of the Resource type to produce history for
615         * @param parameters the parameters for this history interaction
616         * @param returnType the class of the Bundle type to return
617         * @return a Bundle with the type history
618         */
619        default <B extends IBaseBundle, P extends IBaseParameters, T extends IBaseResource> B history(
620                        Class<T> resourceType, P parameters, Class<B> returnType) {
621                return this.history(resourceType, parameters, returnType, Collections.emptyMap());
622        }
623
624        /**
625         * Returns a Bundle with type-level history for this repository
626         *
627         * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a>
628         *
629         * @param <B> a Bundle type to return
630         * @param <P> a Parameters type for input parameters
631         * @param <T> a Resource type to produce history for
632         * @param resourceType the class of the Resource type to produce history for
633         * @param parameters the parameters for this history interaction
634         * @param returnType the class of the Bundle type to return
635         * @param headers headers for this request, typically key-value pairs of HTTP headers
636         * @return a Bundle with the type history
637         */
638        default <B extends IBaseBundle, P extends IBaseParameters, T extends IBaseResource> B history(
639                        Class<T> resourceType, P parameters, Class<B> returnType, Map<String, String> headers) {
640                return throwNotImplementedOperationException("type-level history is not supported by this repository");
641        }
642
643        /**
644         * Returns a Bundle with instance-level history
645         *
646         * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a>
647         *
648         * @param <B> a Bundle type to return
649         * @param <P> a Parameters type for input parameters
650         * @param <I> an Id type for the Resource to produce history for
651         * @param id the id of the Resource type to produce history for
652         * @param parameters the parameters for this history interaction
653         * @param returnType the class of the Bundle type to return
654         * @return a Bundle with the instance history
655         */
656        default <B extends IBaseBundle, P extends IBaseParameters, I extends IIdType> B history(
657                        I id, P parameters, Class<B> returnType) {
658                return this.history(id, parameters, returnType, Collections.emptyMap());
659        }
660
661        /**
662         * Returns a Bundle with instance-level history
663         *
664         * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a>
665         *
666         * @param <B> a Bundle type to return
667         * @param <P> a Parameters type for input parameters
668         * @param <I> an Id type for the Resource to produce history for
669         * @param id the id of the Resource type to produce history for
670         * @param parameters the parameters for this history interaction
671         * @param returnType the class of the Bundle type to return
672         * @param headers headers for this request, typically key-value pairs of HTTP headers
673         * @return a Bundle with the instance history
674         */
675        default <B extends IBaseBundle, P extends IBaseParameters, I extends IIdType> B history(
676                        I id, P parameters, Class<B> returnType, Map<String, String> headers) {
677                return throwNotImplementedOperationException("instance-level history is not supported by this repository");
678        }
679
680        /**
681         * Returns the {@link FhirContext} used by the repository
682         *
683         * Practically, implementing FHIR functionality with the HAPI toolset requires a FhirContext. In
684         * particular for things like version independent code. Ideally, a user could which FHIR version a
685         * repository was configured for using things like the CapabilityStatement. In practice, that's
686         * not widely implemented (yet) and it's expensive to create a new context with every call. We
687         * will probably revisit this in the future.
688         *
689         * @return a FhirContext
690         */
691        FhirContext fhirContext();
692
693        private static <T> T throwNotImplementedOperationException(String theMessage) {
694                throw new NotImplementedOperationException(Msg.code(2542) + theMessage);
695        }
696}