Created
          July 21, 2025 17:12 
        
      - 
      
- 
        Save eldhosejoys/a7b579d9ccdf994f7c0b284cf452e45f to your computer and use it in GitHub Desktop. 
    FHIR JSON validator for the version R4 Schema json from https://hl7.org/fhir/R4/downloads.html and ajv npm library in Express JS
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // server.js | |
| const express = require('express'); | |
| const Ajv = require('ajv'); | |
| const fhirSchema = require('./fhir.schema.json'); // Import the saved FHIR schema | |
| // Initialize Express app | |
| const app = express(); | |
| app.use(express.json()); // Middleware to parse JSON bodies | |
| // Initialize Ajv | |
| const ajv = new Ajv({ strict: false }); | |
| // --- THIS IS THE FIX --- | |
| // Explicitly add the meta-schema for JSON Schema Draft-06 | |
| ajv.addMetaSchema(require('ajv/dist/refs/json-schema-draft-06.json')); | |
| // -------------------- | |
| // Add the entire FHIR schema to Ajv. | |
| // Now Ajv knows how to validate this Draft-06 schema. | |
| ajv.addSchema(fhirSchema, 'fhir.schema.json'); | |
| // Get the specific validator function for the Patient resource definition. | |
| // The '#/definitions/Patient' is a JSON Pointer to the Patient schema within the main file. | |
| const validatePatient = ajv.getSchema('fhir.schema.json#/definitions/Patient'); | |
| // Get the root validator for the entire FHIR schema (for the /Bundle endpoint) | |
| // This will use the "discriminator" to validate any resource type. | |
| const validateFhirResource = ajv.getSchema("http://hl7.org/fhir/json-schema/4.0"); | |
| // --- Create the Validation Endpoint --- | |
| app.post('/Patient', (req, res) => { | |
| // The incoming JSON payload is in req.body | |
| const patientPayload = req.body; | |
| // 1. A basic check to ensure the resourceType matches | |
| if (patientPayload.resourceType !== 'Patient') { | |
| return res.status(400).json({ | |
| isValid: false, | |
| message: "Validation failed: resourceType must be 'Patient'." | |
| }); | |
| } | |
| // 2. Use the compiled validator to check the payload structure | |
| const isValid = validatePatient(patientPayload); | |
| if (isValid) { | |
| // If validation is successful | |
| res.status(200).json({ | |
| isValid: true, | |
| message: 'Patient resource is valid.' | |
| }); | |
| } else { | |
| // If validation fails, return a 400 Bad Request with the validation errors | |
| res.status(400).json({ | |
| isValid: false, | |
| message: 'Patient resource is invalid.', | |
| errors: validatePatient.errors | |
| }); | |
| } | |
| }); | |
| // --- NEW ENDPOINT for a Bundle Resource --- | |
| app.post('/Bundle', (req, res) => { | |
| const bundlePayload = req.body; | |
| if (!validateFhirResource) { | |
| return res.status(500).send("FHIR resource validator not found"); | |
| } | |
| // We can directly validate the bundle. The discriminator will handle the | |
| // specific types of resources within the 'entry' array. | |
| const isValid = validateFhirResource(bundlePayload); | |
| if (isValid) { | |
| res.status(200).json({ isValid: true, message: 'Bundle resource and its contained resources are valid.' }); | |
| } else { | |
| res.status(400).json({ isValid: false, message: 'Bundle resource is invalid.', errors: validateFhirResource.errors }); | |
| } | |
| }); | |
| // Start the server | |
| const PORT = 3000; | |
| app.listen(PORT, () => { | |
| console.log(`Server is running on http://localhost:${PORT}`); | |
| console.log('Post a FHIR Patient JSON object to http://localhost:3000/Patient to validate.'); | |
| }); | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment