fhir_r4_at_rest 0.4.1
fhir_r4_at_rest: ^0.4.1 copied to clipboard
A Dart package providing type-safe, fluent RESTful operations for FHIR R4 resources.
fhir_r4_at_rest #
A Dart package for building FHIR R4 RESTful requests and parsing responses. This package handles request construction and response parsing, while authentication is handled by passing authenticated HTTP clients (e.g., from the fhir_r4_auth package).
FHIR® is the registered trademark of HL7 and is used with the permission of HL7. Use of the FHIR trademark does not constitute endorsement of this product by HL7.
Features #
- Type-safe request builders for all FHIR RESTful operations
- Fluent interface for constructing complex queries
- Resource-specific search parameter builders
- Structured response parsing with
ReturnResults - Works with any HTTP client (authenticated or not)
- Comprehensive parameter validation
Quick Start #
import 'package:fhir_r4_at_rest/fhir_r4_at_rest.dart';
import 'package:fhir_r4/fhir_r4.dart';
// Simple read from an open server
final request = FhirReadRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
);
final response = await request.sendRequest();
final patient = Patient.fromJson(jsonDecode(response.body));
Installation #
dependencies:
fhir_r4_at_rest: ^0.4.0
fhir_r4: ^0.4.2
# Optional: For authenticated requests
fhir_r4_auth: ^0.4.0
FHIR Version Support #
This package supports FHIR R4. For other FHIR versions, see:
fhir_r5_at_rest- R5 supportfhir_r6_at_rest- R6 support
Basic Usage #
Reading a Resource #
final request = FhirReadRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
headers: {'Authorization': 'Bearer token123'},
);
final response = await request.sendRequest();
Creating a Resource #
final patient = Patient(
name: [
HumanName(
family: 'Doe'.toFhirString,
given: ['John'.toFhirString],
),
],
);
final request = FhirCreateRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
resource: patient.toJson(),
headers: {'Authorization': 'Bearer token123'},
);
final response = await request.sendRequest();
Updating a Resource #
final patient = Patient(
id: '12345'.toFhirString,
name: [
HumanName(
family: 'Doe'.toFhirString,
given: ['John'.toFhirString],
),
],
);
final request = FhirUpdateRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
resource: patient.toJson(),
headers: {'Authorization': 'Bearer token123'},
);
final response = await request.sendRequest();
Deleting a Resource #
final request = FhirDeleteRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
headers: {'Authorization': 'Bearer token123'},
);
final response = await request.sendRequest();
Request Parameters #
The library provides a fluent API for building request parameters:
final parameters = RestfulParameters()
.requestPretty()
.addCount(10)
.requestSummary(Summary.true_)
.add('_format', 'json');
final request = FhirReadRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
parameters: parameters,
);
Type-Safe Searching #
The library provides type-safe search builders for FHIR resources:
// Search for active male patients born after 1970
final search = SearchPatient()
.active(FhirString('true'))
.gender(FhirString('male'))
.birthdate(
FhirDateTime('1970-01-01'),
modifier: SearchModifier.gt,
);
final request = FhirSearchRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
search: search,
);
final response = await request.sendRequest();
Advanced Operations #
Working with History #
final request = FhirHistoryRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
parameters: RestfulParameters()
.add('_count', '10')
.add('_since', '2020-01-01'),
);
final response = await request.sendRequest();
Batch and Transaction Operations #
final bundle = Bundle(
type: BundleType.transaction,
entry: [
BundleEntry(
request: BundleRequest(
method: HTTPVerb.POST,
url: FhirUri('Patient'),
),
resource: Patient(
name: [
HumanName(
family: FhirString('Doe'),
given: [FhirString('John')],
),
],
),
),
],
);
final request = FhirTransactionRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
bundle: bundle.toJson(),
);
final response = await request.sendRequest();
Capabilities Statement #
final request = FhirCapabilitiesRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
mode: Mode.normative,
);
final response = await request.sendRequest();
Custom Operations #
final request = FhirOperationRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
operation: 'everything',
parameters: RestfulParameters()
.add('start', '2020-01-01')
.add('end', '2020-12-31'),
);
final response = await request.sendRequest();
Handling Responses #
Basic Response Handling #
try {
final response = await request.sendRequest();
if (response.statusCode == 200) {
final patient = Patient.fromJson(
jsonDecode(response.body),
);
// Work with the patient resource
} else {
// Handle error response
print('Error: ${response.statusCode}');
print('Body: ${response.body}');
}
} catch (e) {
// Handle network or parsing exceptions
print('Exception: $e');
}
Using ReturnResults for Structured Response Handling #
The library provides ReturnResults to separate successful resources from errors:
final response = await request.sendRequest();
final resource = Resource.fromJson(jsonDecode(response.body));
final result = parseRequestResult(resource);
// Check for successfully returned resources
if (result.resources.isNotEmpty) {
for (final resource in result.resources) {
// Process each resource
print('Retrieved resource: ${resource.id}');
}
}
// Check for error OperationOutcomes
if (result.errorOperationOutcomes.isNotEmpty) {
for (final error in result.errorOperationOutcomes) {
print('Error: ${error.issue.first.diagnostics}');
}
}
// Check for informational OperationOutcomes
if (result.informationOperationOutcomes.isNotEmpty) {
for (final info in result.informationOperationOutcomes) {
print('Info: ${info.issue.first.diagnostics}');
}
}
Custom HTTP Client #
final client = http.Client(); // Your custom HTTP client
final request = FhirReadRequest(
base: Uri.parse('http://hapi.fhir.org/baseR4'),
resourceType: 'Patient',
id: '12345',
client: client,
);
Authentication #
This package works with any HTTP client, including authenticated clients from the fhir_r4_auth package.
Using with fhir_r4_auth Package #
import 'package:fhir_r4_auth/fhir_r4_auth.dart';
// Create and authenticate a SMART on FHIR client
final authClient = SmartFhirClient(
fhirUri: FhirUri('https://server.org/fhir'),
clientId: 'my-client-id',
redirectUri: FhirUri('https://myapp.com/callback'),
scopes: ['patient/*.read'],
);
await authClient.login();
// Pass the authenticated client to any request
final request = FhirReadRequest(
base: Uri.parse('https://server.org/fhir'),
resourceType: 'Patient',
id: '12345',
client: authClient, // Authenticated client handles auth headers
);
final response = await request.sendRequest();
Using with Custom Headers #
For simple token-based authentication without a full OAuth flow:
final request = FhirReadRequest(
base: Uri.parse('https://server.org/fhir'),
resourceType: 'Patient',
id: '12345',
headers: {'Authorization': 'Bearer your-access-token'},
);
Using with Any Custom HTTP Client #
// Any client that extends http.Client
final customClient = MyCustomHttpClient();
final request = FhirReadRequest(
base: Uri.parse('https://server.org/fhir'),
resourceType: 'Patient',
id: '12345',
client: customClient,
);
Documentation #
For more detailed documentation, examples, and API reference, visit: FHIR-FLI Documentation
License #
This project is licensed under the MIT License - see the LICENSE file for details.
FHIR® is the registered trademark of Health Level Seven International (HL7) and its use does not constitute endorsement of products by HL7®.