Firely Server
latest

Firely Products

  • Back to all Firely Products

Firely Server Docs:

  • Overview
  • Getting started
  • Setting up Firely Server
  • Maintenance and Management
  • Features and Tools
  • Security and Tools
  • Programming API Reference
    • Architecture
    • Facade
      • Facade setup configuration
      • Exercise: Build your first Facade
      • Prerequisites and Preparations
      • Starting your project
      • Mapping the database
      • Enable Search
        • 1. Create a query
          • Adding classes for the query
          • Adding a constructor
          • Deciding on a FHIR version
          • Handling the search request
          • IFilterValue implementations
      • Next search step
      • Finalizing search
      • Debugging the Facade
      • Finalizing your project
      • Enable changes to the repository
    • Programming API
    • Dependencies and licenses
  • Compliance & Certification
  • Releases
  • FAQ
  • Contact us
Firely Server
    FHIR DevDays banner

  • Firely Docs »
  • Firely Server »
  • Enable Search
  • Edit on GitHub

Enable Search

Enabling search involves two major steps:

  1. Creating a query to the database based on the bits and pieces in the search url

  2. Getting a count and actual data from the database with that query, and map it to a SearchResult

The next paragraphs will walk you through these steps.

1. Create a query

Firely Server Facade is meant to be used across all kinds of database paradigms and schemas. Or even against underlying web services or stored procedures. This means Firely Server cannot prescribe the way your query should be expressed. After all, it could be an http call to a webservice, or a json command to MongoDB.

In our case we will build a LINQ query against our ViSi model, that is translated by Entity Framework to a SQL query. Because this is a quite common case, Firely Server provides a basis for it in the package Vonk.Facade.Relational.

  • Go back to the NuGet Package Manager Console and run Install-Package Vonk.Facade.Relational

Note

If you did this previously for the other Firely Server packages, you can install the latest beta release of this package as well by adding -IncludePrerelease to the install command.

Adding classes for the query

You usually create a query class per ResourceType. The Query object is used to capture the elements of the search that are provided to the QueryFactory.

In this exercise we start with resource type Patient, and will create a PatientQuery and PatientQueryFactory class. Because PatientQuery has no specific content of its own, we will include both in one file.

  • Add a new class PatientQueryFactory to the root of the project

  • Add using statements for Vonk.Facade.Relational, Microsoft.EntityFrameworkCore, and <your project>.Models

  • Above the actual PatientQueryFactory class insert the PatientQuery class:

    public class PatientQuery: RelationalQuery<ViSiPatient>
    {}
    
  • Now flesh out the PatientQueryFactory:

    public class PatientQueryFactory: RelationalQueryFactory<ViSiPatient, PatientQuery>
    {}
    

Adding a constructor

You have to provide a constructor for the factory class. With this you tell Firely Server for which resource type this QueryFactory is valid. The DbContext is used for retrieving DbSets for related entities, as we will see later:

public PatientQueryFactory(DbContext onContext) : base("Patient", onContext) { }

Deciding on a FHIR version

You need to explicitly tell Firely Server for which FHIR version(s) you wish to return resources. If you don’t override EntryInformationModel, any search will fail with a 501 Not Implemented. The following override will allow searches for any possible FHIR version to be handled by your facade:

public override PatientQuery EntryInformationModel(string informationModel)
{
    return default(PatientQuery);
}

If you wish to implement search only for a single FHIR version or for a limited set of versions you can override the method like this:

public override PatientQuery EntryInformationModel(string informationModel)
{
    if (informationModel == VonkConstants.Model.FhirR4)
    {
        return default(PatientQuery);
    }

    throw new NotImplementedException($"FHIR version {informationModel} is not supported");
}

Handling the search request

Each of the searchparameters in the search request triggers a call to the Filter method. This method takes a parameterName and IFilterValue as its arguments.

The parameterName is the searchparameter as it was used in the search url. This name corresponds with the code field in a SearchParameter resource. The IFilterValue value is one of 10 possible implementations, one for each type of SearchParameter. See IFilterValue implementations for a short description of these possibilities.

By default the Filter method dispatches the call to a suitable overload of AddValueFilter, based on the actual type of the value parameter. It is up to you to override the ones you support any parameters for.

  • Override the method PatientQuery AddValueFilter(string parameterName, TokenValue value) in the PatientQueryFactory class to implement support for the _id parameter, which is a token type parameter.

    The _id parameter must be matched against the ViSiPatient.Id property. So we have to:

    • Parse the Token.Code to an integer (ViSiPatient.Id is of type int)

    • Create a query with a predicate on ViSiPatient.Id.

      This is how:

      if (parameterName == "_id")
      {
          if (!int.TryParse(value.Code, out int patientId))
          {
              throw new ArgumentException("Patient Id must be an integer value.");
          }
          else
          {
              return PredicateQuery(vp => vp.Id == patientId);
          }
      }
      return base.AddValueFilter(parameterName, value);
      

Note

The ArgumentException in this code will automatically result in setting the argument status to error, so the Firely Server will send a response with an error code and OperationOutcome. See the information about the IArgumentCollection and IArgument classes in IVonkContext.

That’s it for now, we will add support for another parameter later.

IFilterValue implementations

There are 10 possible implementations you can use as value for the IFilterValue parameter in the Query. The first 7 are the general search parameter types: StringValue, DateTimeValue, TokenValue, NumberValue, QuantityValue, UriValue and ReferenceValue.

Besides that there are two special values for chaining and reverse chaining: ReferenceToValue and ReferenceFromValue.

And finally there is a special value for when Firely Server does not know the SearchParameter and hence not the type of it: RawValue.

Previous Next

© Copyright 2023, Firely. Revision 5238488f.

Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latest
Versions
latest
5.0.0
5.0b1
4.10.1
4.10.0
4.9.3
4.9.2
4.9.1
4.9.0
4.8.0
4.7.1
4.7.0
4.6.2
4.6.1
4.6.0
4.5.1
4.5.0
4.4.0
4.3.0
Downloads
html
epub
On Read the Docs
Project Home
Builds