
001/*- 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2026 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.repository.impl.MultiMapRepositoryRestQueryBuilder; 026import ca.uhn.fhir.rest.api.MethodOutcome; 027import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; 028import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException; 029import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 030import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException; 031import com.google.common.annotations.Beta; 032import com.google.common.collect.Multimap; 033import com.google.common.collect.Multimaps; 034import jakarta.annotation.Nonnull; 035import org.hl7.fhir.instance.model.api.IBaseBundle; 036import org.hl7.fhir.instance.model.api.IBaseConformance; 037import org.hl7.fhir.instance.model.api.IBaseParameters; 038import org.hl7.fhir.instance.model.api.IBaseResource; 039import org.hl7.fhir.instance.model.api.IIdType; 040 041import java.util.Collections; 042import java.util.List; 043import java.util.Map; 044 045/** 046 * <p> 047 * This API is under-going active development, so it should be considered beta-level. 048 * </p> 049 * 050 * <p> 051 * This interface is a Java rendition of the FHIR REST API. All FHIR operations are defined at the 052 * HTTP level, which is convenient from the specification point-of-view since FHIR is built on top 053 * of web standards. This does mean that a few HTTP specific considerations, such as transmitting 054 * side-band information through the HTTP headers, bleeds into this API. 055 * </p> 056 * 057 * <p> 058 * One particularly odd case are FHIR Bundle links. The specification describes these as opaque to 059 * the end-user, so a given FHIR repository implementation must be able to resolve those directly. 060 * See {@link IRepository#link(Class, String)} 061 * </p> 062 * 063 * <p> 064 * This interface also chooses to ignore return headers for most cases, preferring to return the 065 * Java objects directly. In cases where this is not possible, or the additional headers are crucial 066 * information, HAPI's {@link MethodOutcome} is used. 067 * </p> 068 * 069 * <p> 070 * Implementations of this interface should prefer to throw the exceptions derived from 071 * {@link ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException} 072 * 073 * All operations may throw {@link AuthenticationException}, {@link ForbiddenOperationException}, or 074 * {@link InternalErrorException} in addition to operation-specific exceptions. 075 * </p> 076 * 077 * <p> 078 * If a given operation is not supported, implementations should throw an 079 * {@link NotImplementedOperationException}. The capabilities operation, if supported, should return 080 * the set of supported interactions. If capabilities is not supported, the components in this 081 * repository will try to invoke operations with "sensible" defaults. For example, by using the 082 * standard FHIR search parameters. Discussion is on-going to determine what a "sensible" minimal 083 * level of support for interactions should be. 084 * </p> 085 * 086 * <p> 087 * Note to implementors: this interface exposes several search() methods. 088 * Several are deprecated and present for source-compatibility with previous versions 089 * of this interface used by the clinical reasoning project. 090 * They will be removed at a future date. 091 * We provide two main apis with different payloads for the query parameters: a Multimap method, 092 * and an abstract builder callback which is compatible with SearchParameterMap. 093 * Implementations must implement at least one of these two. 094 * We provide default implementations of each in terms of the other so you only need to implement one. 095 * Note that the SearchParameterMap used by the JPA repository implements the interface, and can be used as is. 096 * </p> 097 * 098 * @see <a href="https://www.hl7.org/fhir/http.html">FHIR REST API</a> 099 */ 100@Beta 101public interface IRepository { 102 103 // CRUD starts here 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 * @return the Resource 116 */ 117 default <T extends IBaseResource, I extends IIdType> T read(Class<T> resourceType, I id) { 118 return this.read(resourceType, id, Collections.emptyMap()); 119 } 120 121 /** 122 * Reads a Resource from the repository 123 * 124 * @see <a href="https://www.hl7.org/fhir/http.html#read">FHIR read</a> 125 * @see <a href="https://www.hl7.org/fhir/http.html#vread">FHIR vRead</a> 126 * 127 * @param <T> a Resource type 128 * @param <I> an Id type 129 * @param resourceType the class of the Resource type to read 130 * @param id the id of the Resource to read 131 * @param headers headers for this request, typically key-value pairs of HTTP headers 132 * @return the Resource 133 */ 134 <T extends IBaseResource, I extends IIdType> T read(Class<T> resourceType, I id, Map<String, String> headers); 135 136 /** 137 * Creates a Resource in the repository 138 * 139 * @see <a href="https://www.hl7.org/fhir/http.html#create">FHIR create</a> 140 * 141 * @param <T> a Resource type 142 * @param resource the Resource to create 143 * @return a MethodOutcome with the id of the created Resource 144 */ 145 default <T extends IBaseResource> MethodOutcome create(T resource) { 146 return this.create(resource, Collections.emptyMap()); 147 } 148 149 /** 150 * Creates a Resource in the repository 151 * 152 * @see <a href="https://www.hl7.org/fhir/http.html#create">FHIR create</a> 153 * 154 * @param <T> a Resource type 155 * @param resource the Resource to create 156 * @param headers headers for this request, typically key-value pairs of HTTP headers 157 * @return a MethodOutcome with the id of the created Resource 158 */ 159 <T extends IBaseResource> MethodOutcome create(T resource, Map<String, String> headers); 160 161 /** 162 * Patches a Resource in the repository 163 * 164 * @see <a href="https://www.hl7.org/fhir/http.html#patch">FHIR patch</a> 165 * 166 * @param <I> an Id type 167 * @param <P> a Parameters type 168 * @param id the id of the Resource to patch 169 * @param patchParameters parameters describing the patches to apply 170 * @return a MethodOutcome with the id of the patched resource 171 */ 172 default <I extends IIdType, P extends IBaseParameters> MethodOutcome patch(I id, P patchParameters) { 173 return this.patch(id, patchParameters, Collections.emptyMap()); 174 } 175 176 /** 177 * Patches a Resource in the repository 178 * 179 * @see <a href="https://www.hl7.org/fhir/http.html#patch">FHIR patch</a> 180 * 181 * @param <I> an Id type 182 * @param <P> a Parameters type 183 * @param id the id of the Resource to patch 184 * @param patchParameters parameters describing the patches to apply 185 * @param headers headers for this request, typically key-value pairs of HTTP headers 186 * @return a MethodOutcome with the id of the patched resource 187 */ 188 default <I extends IIdType, P extends IBaseParameters> MethodOutcome patch( 189 I id, P patchParameters, Map<String, String> headers) { 190 return throwNotImplementedOperationException("patch is not supported by this repository"); 191 } 192 193 /** 194 * Updates a Resource in the repository 195 * 196 * @see <a href="https://www.hl7.org/fhir/http.html#update">FHIR update</a> 197 * 198 * @param <T> a Resource type 199 * @param resource the Resource to update 200 * @return a MethodOutcome with the id of the updated Resource 201 */ 202 default <T extends IBaseResource> MethodOutcome update(T resource) { 203 return this.update(resource, Collections.emptyMap()); 204 } 205 206 /** 207 * Updates a Resource in the repository 208 * 209 * @see <a href="https://www.hl7.org/fhir/http.html#update">FHIR update</a> 210 * 211 * @param <T> a Resource type 212 * @param resource the Resource to update 213 * @param headers headers for this request, typically key-value pairs of HTTP headers 214 * @return a MethodOutcome with the id of the updated Resource 215 */ 216 <T extends IBaseResource> MethodOutcome update(T resource, Map<String, String> headers); 217 218 /** 219 * Deletes a Resource in the repository 220 * 221 * @see <a href="https://www.hl7.org/fhir/http.html#delete">FHIR delete</a> 222 * 223 * @param <T> a Resource type 224 * @param <I> an Id type 225 * @param resourceType the class of the Resource type to delete 226 * @param id the id of the Resource to delete 227 * @return a MethodOutcome with the id of the deleted resource 228 */ 229 default <T extends IBaseResource, I extends IIdType> MethodOutcome delete(Class<T> resourceType, I id) { 230 return this.delete(resourceType, id, Collections.emptyMap()); 231 } 232 233 /** 234 * Deletes a Resource in the repository 235 * 236 * @see <a href="https://www.hl7.org/fhir/http.html#delete">FHIR delete</a> 237 * 238 * @param <T> a Resource type 239 * @param <I> an Id type 240 * @param resourceType the class of the Resource type to delete 241 * @param id the id of the Resource to delete 242 * @param headers headers for this request, typically key-value pairs of HTTP headers 243 * @return a MethodOutcome with the id of the deleted resource 244 */ 245 <T extends IBaseResource, I extends IIdType> MethodOutcome delete( 246 Class<T> resourceType, I id, Map<String, String> headers); 247 248 // Querying starts here 249 250 /** 251 * Searches this repository 252 * 253 * @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a> 254 * 255 * @param <B> a Bundle type 256 * @param <T> a Resource type 257 * @param bundleType the class of the Bundle type to return 258 * @param resourceType the class of the Resource type to search 259 * @param searchParameters the searchParameters for this search 260 * @return a Bundle with the results of the search 261 */ 262 default <B extends IBaseBundle, T extends IBaseResource> B search( 263 Class<B> bundleType, Class<T> resourceType, Multimap<String, List<IQueryParameterType>> searchParameters) { 264 return this.search(bundleType, resourceType, searchParameters, Collections.emptyMap()); 265 } 266 267 /** 268 * Searches this repository 269 * 270 * @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a> 271 * 272 * @param <B> a Bundle type 273 * @param <T> a Resource type 274 * @param bundleType the class of the Bundle type to return 275 * @param resourceType the class of the Resource type to search 276 * @param searchParameters the searchParameters for this search 277 * @return a Bundle with the results of the search 278 * @deprecated since 8.4 use Multimap or IRepositoryRestQueryContributor with SearchParameterMap instead 279 */ 280 @Deprecated(since = "8.4.0") 281 default <B extends IBaseBundle, T extends IBaseResource> B search( 282 Class<B> bundleType, Class<T> resourceType, Map<String, List<IQueryParameterType>> searchParameters) { 283 return this.search(bundleType, resourceType, searchParameters, Collections.emptyMap()); 284 } 285 286 /** 287 * Searches this repository 288 * 289 * @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a> 290 * 291 * @param <B> a Bundle type 292 * @param <T> a Resource type 293 * @param theBundleType the class of the Bundle type to return 294 * @param theResourceType the class of the Resource type to search 295 * @param theSearchParameters the searchParameters for this search 296 * @param theHeaders headers for this request, typically key-value pairs of HTTP headers 297 * @return a Bundle with the results of the search 298 */ 299 default <B extends IBaseBundle, T extends IBaseResource> B search( 300 Class<B> theBundleType, 301 Class<T> theResourceType, 302 Multimap<String, List<IQueryParameterType>> theSearchParameters, 303 Map<String, String> theHeaders) { 304 // we have a cycle of default implementations between this and the search builder version. 305 // Implementors MUST implement one or the other or both. 306 return this.search(theBundleType, theResourceType, sb -> sb.addAll(theSearchParameters), theHeaders); 307 } 308 309 /** 310 * Searches this repository 311 * 312 * @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a> 313 * 314 * @param <B> a Bundle type 315 * @param <T> a Resource type 316 * @param theBundleType the class of the Bundle type to return 317 * @param theResourceType the class of the Resource type to search 318 * @param theQueryContributor the searchParameters for this search 319 * @param theHeaders headers for this request, typically key-value pairs of HTTP headers 320 * @return a Bundle with the results of the search 321 */ 322 default <B extends IBaseBundle, T extends IBaseResource> B search( 323 Class<B> theBundleType, 324 Class<T> theResourceType, 325 IRepositoryRestQueryContributor theQueryContributor, 326 Map<String, String> theHeaders) { 327 // we have a cycle of default implementations between this and the multi-map version. 328 // Implementors MUST implement one or the other for now. 329 return this.search( 330 theBundleType, 331 theResourceType, 332 MultiMapRepositoryRestQueryBuilder.contributorToMultimap(theQueryContributor), 333 theHeaders); 334 } 335 336 /** 337 * Searches this repository 338 * 339 * @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a> 340 * 341 * @param <B> a Bundle type 342 * @param <T> a Resource type 343 * @param bundleType the class of the Bundle type to return 344 * @param resourceType the class of the Resource type to search 345 * @param searchParameters the searchParameters for this search 346 * @param headers headers for this request, typically key-value pairs of HTTP headers 347 * @return a Bundle with the results of the search 348 * @deprecated since 8.4 use Multimap or IRepositoryRestQueryContributor with SearchParameterMap instead 349 */ 350 @Deprecated(since = "8.4.0") 351 default <B extends IBaseBundle, T extends IBaseResource> B search( 352 Class<B> bundleType, 353 Class<T> resourceType, 354 Map<String, List<IQueryParameterType>> searchParameters, 355 Map<String, String> headers) { 356 return this.search(bundleType, resourceType, Multimaps.forMap(searchParameters), headers); 357 } 358 359 // Paging starts here 360 361 /** 362 * Reads a Bundle from a link on this repository 363 * This is typically used for paging during searches 364 * 365 * @see <a href="https://www.hl7.org/fhir/bundle-definitions.html#Bundle.link">FHIR Bundle 366 * link</a> 367 * 368 * @param <B> a Bundle type 369 * @param url the url of the Bundle to load 370 * @return a Bundle 371 */ 372 default <B extends IBaseBundle> B link(Class<B> bundleType, String url) { 373 return this.link(bundleType, url, Collections.emptyMap()); 374 } 375 376 /** 377 * Reads a Bundle from a link on this repository 378 * This is typically used for paging during searches 379 * 380 * @see <a href="https://www.hl7.org/fhir/bundle-definitions.html#Bundle.link">FHIR Bundle 381 * link</a> 382 * 383 * @param <B> a Bundle type 384 * @param url the url of the Bundle to load 385 * @param headers headers for this request, typically key-value pairs of HTTP headers 386 * @return a Bundle 387 */ 388 default <B extends IBaseBundle> B link(Class<B> bundleType, String url, Map<String, String> headers) { 389 return throwNotImplementedOperationException("link is not supported by this repository"); 390 } 391 392 // Metadata starts here 393 394 /** 395 * Returns the CapabilityStatement/Conformance metadata for this repository 396 * 397 * @see <a href="https://www.hl7.org/fhir/http.html#capabilities">FHIR capabilities</a> 398 * 399 * @param <C> a CapabilityStatement/Conformance type 400 * @param resourceType the class of the CapabilityStatement/Conformance to return 401 * @return a CapabilityStatement/Conformance with the repository's metadata 402 */ 403 default <C extends IBaseConformance> C capabilities(Class<C> resourceType) { 404 return this.capabilities(resourceType, Collections.emptyMap()); 405 } 406 407 /** 408 * Returns the CapabilityStatement/Conformance metadata for this repository 409 * 410 * @see <a href="https://www.hl7.org/fhir/http.html#capabilities">FHIR capabilities</a> 411 * 412 * @param <C> a CapabilityStatement/Conformance type 413 * @param resourceType the class of the CapabilityStatement/Conformance to return 414 * @param headers headers for this request, typically key-value pairs of HTTP headers 415 * @return a CapabilityStatement/Conformance with the repository's metadata 416 */ 417 default <C extends IBaseConformance> C capabilities(Class<C> resourceType, Map<String, String> headers) { 418 return throwNotImplementedOperationException("capabilities is not supported by this repository"); 419 } 420 421 // Transactions starts here 422 423 /** 424 * Performs a transaction or batch on this repository 425 * 426 * @see <a href="https://www.hl7.org/fhir/http.html#transaction">FHIR transaction</a> 427 * 428 * @param <B> a Bundle type 429 * @param transaction a Bundle with the transaction/batch 430 * @return a Bundle with the results of the transaction/batch 431 */ 432 default <B extends IBaseBundle> B transaction(B transaction) { 433 return this.transaction(transaction, Collections.emptyMap()); 434 } 435 436 /** 437 * Performs a transaction or batch on this repository 438 * 439 * @see <a href="https://www.hl7.org/fhir/http.html#transaction">FHIR transaction</a> 440 * 441 * @param <B> a Bundle type 442 * @param transaction a Bundle with the transaction/batch 443 * @param headers headers for this request, typically key-value pairs of HTTP headers 444 * @return a Bundle with the results of the transaction/batch 445 */ 446 default <B extends IBaseBundle> B transaction(B transaction, Map<String, String> headers) { 447 return throwNotImplementedOperationException("transaction is not supported by this repository"); 448 } 449 450 // Operations starts here 451 452 /** 453 * Invokes a server-level operation on this repository that returns a Resource 454 * 455 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 456 * 457 * @param <R> a Resource type to return 458 * @param <P> a Parameters type for operation parameters 459 * @param name the name of the operation to invoke 460 * @param parameters the operation parameters 461 * @param returnType the class of the Resource the operation returns 462 * @return the results of the operation 463 */ 464 default <R extends IBaseResource, P extends IBaseParameters> R invoke( 465 String name, P parameters, Class<R> returnType) { 466 return this.invoke(name, parameters, returnType, Collections.emptyMap()); 467 } 468 469 /** 470 * Invokes a server-level operation on this repository that returns a Resource 471 * 472 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 473 * 474 * @param <R> a Resource type to return 475 * @param <P> a Parameters type for operation parameters 476 * @param name the name of the operation to invoke 477 * @param parameters the operation parameters 478 * @param returnType the class of the Resource the operation returns 479 * @param headers headers for this request, typically key-value pairs of HTTP headers 480 * @return the results of the operation 481 */ 482 default <R extends IBaseResource, P extends IBaseParameters> R invoke( 483 String name, P parameters, Class<R> returnType, Map<String, String> headers) { 484 return throwNotImplementedOperationException("server-level invoke is not supported by this repository"); 485 } 486 487 /** 488 * Invokes a server-level operation on this repository 489 * 490 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 491 * 492 * @param <P> a Parameters type for operation parameters 493 * @param name the name of the operation to invoke 494 * @param parameters the operation parameters 495 * @return a MethodOutcome with a status code 496 */ 497 default <P extends IBaseParameters> MethodOutcome invoke(String name, P parameters) { 498 return this.invoke(name, parameters, Collections.emptyMap()); 499 } 500 501 /** 502 * Invokes a server-level operation on this repository 503 * 504 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 505 * 506 * @param <P> a Parameters type for operation parameters 507 * @param name the name of the operation to invoke 508 * @param parameters the operation parameters 509 * @param headers headers for this request, typically key-value pairs of HTTP headers 510 * @return a MethodOutcome with a status code 511 */ 512 default <P extends IBaseParameters> MethodOutcome invoke(String name, P parameters, Map<String, String> headers) { 513 return throwNotImplementedOperationException("server-level invoke is not supported by this repository"); 514 } 515 516 /** 517 * Invokes a type-level operation on this repository that returns a Resource 518 * 519 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 520 * 521 * @param <R> a Resource type to return 522 * @param <P> a Parameters type for operation parameters 523 * @param <T> a Resource type to do the invocation for 524 * @param resourceType the class of the Resource to do the invocation for 525 * @param name the name of the operation to invoke 526 * @param parameters the operation parameters 527 * @param returnType the class of the Resource the operation returns 528 * @return the results of the operation 529 */ 530 default <R extends IBaseResource, P extends IBaseParameters, T extends IBaseResource> R invoke( 531 Class<T> resourceType, String name, P parameters, Class<R> returnType) { 532 return this.invoke(resourceType, name, parameters, returnType, Collections.emptyMap()); 533 } 534 535 /** 536 * Invokes a type-level operation on this repository that returns a Resource 537 * 538 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 539 * 540 * @param <R> a Resource type to return 541 * @param <P> a Parameters type for operation parameters 542 * @param <T> a Resource type to do the invocation for 543 * @param resourceType the class of the Resource to do the invocation for 544 * @param name the name of the operation to invoke 545 * @param parameters the operation parameters 546 * @param headers headers for this request, typically key-value pairs of HTTP headers 547 * @param returnType the class of the Resource the operation returns 548 * @return the results of the operation 549 */ 550 default <R extends IBaseResource, P extends IBaseParameters, T extends IBaseResource> R invoke( 551 Class<T> resourceType, String name, P parameters, Class<R> returnType, Map<String, String> headers) { 552 return throwNotImplementedOperationException("type-level invoke is not supported by this repository"); 553 } 554 555 /** 556 * Invokes a type-level operation on this repository 557 * 558 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 559 * 560 * @param <P> a Parameters type for operation parameters 561 * @param <T> a Resource type to do the invocation for 562 * @param resourceType the class of the Resource to do the invocation for 563 * @param name the name of the operation to invoke 564 * @param parameters the operation parameters 565 * @return a MethodOutcome with a status code 566 */ 567 default <P extends IBaseParameters, T extends IBaseResource> MethodOutcome invoke( 568 Class<T> resourceType, String name, P parameters) { 569 return this.invoke(resourceType, name, parameters, Collections.emptyMap()); 570 } 571 572 /** 573 * Invokes a type-level operation on this repository 574 * 575 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 576 * 577 * @param <P> a Parameters type for operation parameters 578 * @param <T> a Resource type to do the invocation for 579 * @param resourceType the class of the Resource to do the invocation for 580 * @param name the name of the operation to invoke 581 * @param parameters the operation parameters 582 * @param headers headers for this request, typically key-value pairs of HTTP headers 583 * @return a MethodOutcome with a status code 584 */ 585 default <P extends IBaseParameters, T extends IBaseResource> MethodOutcome invoke( 586 Class<T> resourceType, String name, P parameters, Map<String, String> headers) { 587 return throwNotImplementedOperationException("type-level invoke is not supported by this repository"); 588 } 589 590 /** 591 * Invokes an instance-level operation on this repository that returns a Resource 592 * 593 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 594 * 595 * @param <R> a Resource type to return 596 * @param <P> a Parameters type for operation parameters 597 * @param <I> an Id type 598 * @param id the id of the Resource to do the invocation on 599 * @param name the name of the operation to invoke 600 * @param parameters the operation parameters 601 * @param returnType the class of the Resource the operation returns 602 * @return the results of the operation 603 */ 604 default <R extends IBaseResource, P extends IBaseParameters, I extends IIdType> R invoke( 605 I id, String name, P parameters, Class<R> returnType) { 606 return this.invoke(id, name, parameters, returnType, Collections.emptyMap()); 607 } 608 609 /** 610 * Invokes an instance-level operation on this repository that returns a Resource 611 * 612 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 613 * 614 * @param <R> a Resource type to return 615 * @param <P> a Parameters type for operation parameters 616 * @param <I> an Id type 617 * @param id the id of the Resource to do the invocation on 618 * @param name the name of the operation to invoke 619 * @param parameters the operation parameters 620 * @param returnType the class of the Resource the operation returns 621 * @param headers headers for this request, typically key-value pairs of HTTP headers 622 * @return the results of the operation 623 */ 624 default <R extends IBaseResource, P extends IBaseParameters, I extends IIdType> R invoke( 625 I id, String name, P parameters, Class<R> returnType, Map<String, String> headers) { 626 return throwNotImplementedOperationException("instance-level invoke is not supported by this repository"); 627 } 628 629 /** 630 * Invokes an instance-level operation on this repository 631 * 632 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 633 * 634 * @param <P> a Parameters type for operation parameters 635 * @param <I> an Id type 636 * @param id the id of the Resource to do the invocation on 637 * @param name the name of the operation to invoke 638 * @param parameters the operation parameters 639 * @return a MethodOutcome with a status code 640 */ 641 default <P extends IBaseParameters, I extends IIdType> MethodOutcome invoke(I id, String name, P parameters) { 642 return this.invoke(id, name, parameters, Collections.emptyMap()); 643 } 644 645 /** 646 * Invokes an instance-level operation on this repository 647 * 648 * @see <a href="https://www.hl7.org/fhir/operations.html">FHIR operations</a> 649 * 650 * @param <P> a Parameters type for operation parameters 651 * @param <I> an Id type 652 * @param id the id of the Resource to do the invocation on 653 * @param name the name of the operation to invoke 654 * @param parameters the operation parameters 655 * @param headers headers for this request, typically key-value pairs of HTTP headers 656 * @return a MethodOutcome with a status code 657 */ 658 default <P extends IBaseParameters, I extends IIdType> MethodOutcome invoke( 659 I id, String name, P parameters, Map<String, String> headers) { 660 return throwNotImplementedOperationException("instance-level invoke is not supported by this repository"); 661 } 662 663 // History starts here 664 665 /** 666 * Returns a Bundle with server-level history for this repository 667 * 668 * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a> 669 * 670 * @param <B> a Bundle type to return 671 * @param <P> a Parameters type for input parameters 672 * @param parameters the parameters for this history interaction 673 * @param returnType the class of the Bundle type to return 674 * @return a Bundle with the server history 675 */ 676 default <B extends IBaseBundle, P extends IBaseParameters> B history(P parameters, Class<B> returnType) { 677 return this.history(parameters, returnType, Collections.emptyMap()); 678 } 679 680 /** 681 * Returns a Bundle with server-level history for this repository 682 * 683 * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a> 684 * 685 * @param <B> a Bundle type to return 686 * @param <P> a Parameters type for input parameters 687 * @param parameters the parameters for this history interaction 688 * @param returnType the class of the Bundle type to return 689 * @param headers headers for this request, typically key-value pairs of HTTP headers 690 * @return a Bundle with the server history 691 */ 692 default <B extends IBaseBundle, P extends IBaseParameters> B history( 693 P parameters, Class<B> returnType, Map<String, String> headers) { 694 return throwNotImplementedOperationException("server-level history is not supported by this repository"); 695 } 696 697 /** 698 * Returns a Bundle with type-level history for this repository 699 * 700 * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a> 701 * 702 * @param <B> a Bundle type to return 703 * @param <P> a Parameters type for input parameters 704 * @param <T> a Resource type to produce history for 705 * @param resourceType the class of the Resource type to produce history for 706 * @param parameters the parameters for this history interaction 707 * @param returnType the class of the Bundle type to return 708 * @return a Bundle with the type history 709 */ 710 default <B extends IBaseBundle, P extends IBaseParameters, T extends IBaseResource> B history( 711 Class<T> resourceType, P parameters, Class<B> returnType) { 712 return this.history(resourceType, parameters, returnType, Collections.emptyMap()); 713 } 714 715 /** 716 * Returns a Bundle with type-level history for this repository 717 * 718 * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a> 719 * 720 * @param <B> a Bundle type to return 721 * @param <P> a Parameters type for input parameters 722 * @param <T> a Resource type to produce history for 723 * @param resourceType the class of the Resource type to produce history for 724 * @param parameters the parameters for this history interaction 725 * @param returnType the class of the Bundle type to return 726 * @param headers headers for this request, typically key-value pairs of HTTP headers 727 * @return a Bundle with the type history 728 */ 729 default <B extends IBaseBundle, P extends IBaseParameters, T extends IBaseResource> B history( 730 Class<T> resourceType, P parameters, Class<B> returnType, Map<String, String> headers) { 731 return throwNotImplementedOperationException("type-level history is not supported by this repository"); 732 } 733 734 /** 735 * Returns a Bundle with instance-level history 736 * 737 * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a> 738 * 739 * @param <B> a Bundle type to return 740 * @param <P> a Parameters type for input parameters 741 * @param <I> an Id type for the Resource to produce history for 742 * @param id the id of the Resource type to produce history for 743 * @param parameters the parameters for this history interaction 744 * @param returnType the class of the Bundle type to return 745 * @return a Bundle with the instance history 746 */ 747 default <B extends IBaseBundle, P extends IBaseParameters, I extends IIdType> B history( 748 I id, P parameters, Class<B> returnType) { 749 return this.history(id, parameters, returnType, Collections.emptyMap()); 750 } 751 752 /** 753 * Returns a Bundle with instance-level history 754 * 755 * @see <a href="https://www.hl7.org/fhir/http.html#history">FHIR history</a> 756 * 757 * @param <B> a Bundle type to return 758 * @param <P> a Parameters type for input parameters 759 * @param <I> an Id type for the Resource to produce history for 760 * @param id the id of the Resource type to produce history for 761 * @param parameters the parameters for this history interaction 762 * @param returnType the class of the Bundle type to return 763 * @param headers headers for this request, typically key-value pairs of HTTP headers 764 * @return a Bundle with the instance history 765 */ 766 default <B extends IBaseBundle, P extends IBaseParameters, I extends IIdType> B history( 767 I id, P parameters, Class<B> returnType, Map<String, String> headers) { 768 return throwNotImplementedOperationException("instance-level history is not supported by this repository"); 769 } 770 771 /** 772 * Returns the {@link FhirContext} used by the repository 773 * <p> 774 * Practically, implementing FHIR functionality with the HAPI toolset requires a FhirContext. In 775 * particular for things like version independent code. Ideally, a user could which FHIR version a 776 * repository was configured for using things like the CapabilityStatement. In practice, that's 777 * not widely implemented (yet) and it's expensive to create a new context with every call. We 778 * will probably revisit this in the future. 779 * 780 * @return a FhirContext 781 */ 782 @Nonnull 783 FhirContext fhirContext(); 784 785 private static <T> T throwNotImplementedOperationException(String theMessage) { 786 throw new NotImplementedOperationException(Msg.code(2542) + theMessage); 787 } 788 789 /** 790 * Callback interface for search() methods that use a builder to construct the query. 791 */ 792 @FunctionalInterface 793 interface IRepositoryRestQueryContributor { 794 void contributeToQuery(IRepositoryRestQueryBuilder theBuilder); 795 } 796}