Skip to main content
Link Menu Expand (external link) Document Search Copy Copied

FHIR Resource Validation

FHIR Resource validation is performed by the HL7® FHIR Java Validator. Two validator “wrapper” services are currently included in the Inferno framework:

When creating a Test Kit based on the Inferno Template, IG packages do not need to be included if the IG is available from the FHIR package server. If you need to validate against an unpublished IG, place the .tgz IG packages in lib/YOUR_TEST_KIT_NAME/igs. At runtime, all IG packages in lib/YOUR_TEST_KIT_NAME/igs as well as those in corresponding locations in other loaded test kits, are copied to data/igs, and the validator accesses the IG files from that location. Do not manually edit the contents of data/igs, as the contents are automatically deleted prior to loading.

Defining Validators

The Inferno Template defines one basic validator in the suite. The validator must be configured to reference the IG being tested against. IGs may be referenced by package identifier (for example, 'hl7.fhir.us.core#1.0.0') if they are published, or by filename. It is not necessary to alter the template suite further unless you need multiple validators or want to add extra validator behaviors. Validators are defined with fhir_resource_validator:

fhir_resource_validator :optional_validator_name do
  # Read the validator URL from an environment variable (optional)
  url ENV.fetch('FHIR_RESOURCE_VALIDATOR_URL')

  # Specify the IG(s) to validate resources against
 igs 'identifier#version' # Use this method for published IGs/versions
 igs 'igs/filename.tgz'   # Use this otherwise
 igs 'ig1#v', 'ig2#v'     # Specify all IGs in one line if multiple are needed
end

The url defaults to reading from the FHIR_RESOURCE_VALIDATOR_URL environment variable, so if you have not modified the validator service or environment variables, this line may be omitted.

If no igs are specified, the validator will only support validation against base FHIR definitions, and attempting to validate against specific profile URLs will result in errors.

fhir_resource_validator in the API docs

Validating FHIR Resources

The resource_is_valid? method will validate a FHIR resource and add any validation messages to the runnable.

You can optionally skip adding validation messages by setting add_messages_to_runnable: false.

The validator_response_details parameter allows you to capture the detailed validator output for custom processing. Pass an empty array, and it will be populated with all validation issues. See Accessing Detailed Validation Results for more information.

test do
  fhir_read(:patient, '123')

  # Validate the resource from the last request
  if resource_is_valid?
  end

  # Validate the resource from last request without adding messages to the runnable
  if resource_is_valid?(add_messages_to_runnable: false)
  end

  # Validate some other resource
  if resource_is_valid?(resource: some_other_resource)
  end

  # Validate against a particular profile
  if resource_is_valid?(profile_url: 'http://example.com/fhir_profile_url')
  end

  # Validate using a particular named validator
  if resource_is_valid?(validator: :my_customized_validator)
  end

  # Capture detailed validation results for custom processing
  validation_details = []
  unless resource_is_valid?(validator_response_details: validation_details, add_messages_to_runnable: false)
    # Resource is invalid, analyze the detailed error information
    validation_details.select { |issue| issue.severity == 'error' }.each do |issue|
      add_message('error', issue.message) if issue_of_interest?(issue)
    end
  end
end

resource_is_valid? in the API docs

assert_valid_resource will validate the resource, add any validation messages to the runnable, and fail the test if the resource is invalid.

test do
  fhir_read(:patient, '123')

  # Use the resource from the last request
  assert_valid_resource

  # Validate some other resource
  assert_valid_resource(resource: some_other_resource)

  # Validate against a particular profile
  assert_valid_resource(profile_url: 'http://example.com/fhir_profile_url')

  # Validate using a particular named validator
  assert_valid_resource(validator: :my_customized_validator)
end

assert_valid_resource in the API docs

Filtering Validation Messages

If you need to ignore certain validation messages in your test kit, this can be done using the exclude_message method in the validator definition.

fhir_resource_validator do
  # Messages will be excluded if the block evaluates to a truthy value
  exclude_message do |message|
    message.type == 'info' ||
      message.message.include?('message to ignore') ||
      message.message.match?(/regex_filter/)
  end
end

Performing Additional Validation

Custom Validation Logic

If you want to perform validation steps in addition to the FHIR validation, you can use the perform_additional_validation method in the validator definition. The method can also be used multiple times in a single validator definition to add multiple validation steps. To add additional validation messages, the block in this method must return a single Hash with a type and message, or an Array of Hashes with those keys. If the block returns nil, no new messages are added. The resource is considered invalid if any messages with a type of error are present.

fhir_resource_validator do
  perform_additional_validation do |resource, profile_url|
    if something_is_wrong
      { type: 'error', message: 'something is wrong'}
    end
  end
end

Accessing Detailed Validation Results

The validator_response_details parameter provides access to the complete validation output from the validator service, including both filtered and unfiltered issues. This is useful when you need to perform custom analysis, present validation results differently, or implement conditional logic based on specific validation patterns.

When you pass an empty array to validator_response_details, it will be populated with validator issue objects that contain the full formatted response from the validator service. Each issue includes a filtered flag that indicates whether the issue would have been excluded by default filtering rules (such as those defined by exclude_message).

Validator Issue Structure

Each validator issue object in the validator_response_details array contains:

  • message (String): The formatted validation message, including location information
  • severity (String): The severity level - 'error', 'warning', or 'info'
  • location (String): The location in the resource where the issue was found
  • filtered (Boolean): Whether this issue would be filtered out by default exclusion rules
  • slice_info (Array): Nested validator issues/information (each with the same structure); typically provide details of the base-level issue, including any sub-errors or warnings
  • resource (FHIR::Model): The resource being validated
  • raw_issue (Hash): The complete raw issue hash from the validator service

MustSupport Test using the Evaluator

Checking the presence of Must Support elements is a common feature across test kits and its implementation has been copy-and-pasted between them. To improve the productivity of developing test kits, the Evaluator CLI is built into inferno core, and the MustSupport checks can also be invoked in the context of a test kit by a single method.

To invoke the MustSupport checks, add the following code into test:

assert_must_support_elements_present(resources, profile_url, metadata)

Refer to the assertion API documentation below:

assert_must_support_elements_present

Refer to the examples used in IGs below:

CARIN for BlueButton IG Test kit

International Patient Summary IG Test kit

Suggest an improvement

Want to make an change? Contribute an edit for this page on the Inferno Framework GitHub repository.