Creating an OCR API with FaaS on Azure – Part 1: Architecture and Secure Upload

Recently, I've been working on an OCR system focused on reading digital medical prescriptions. The goal is simple: to allow healthcare professionals and pharmacies to automate the interpretation of medical prescriptions from images sent via API. All of this with security, scalability, and without the headache of credential management. In this first article of the series, I'll show how I designed the architecture, the justification for using Azure Functions, and how I integrated with Blob Storage using Managed Identity. By the end, we'll have a functional endpoint for secure image upload. Shall we? Why Azure Functions? The choice of Azure Functions came naturally for several reasons: Serverless: I don't need to worry about infrastructure. Scalable: The system will handle many image uploads, so scaling on demand is essential. Integrated with the Azure ecosystem: especially Blob Storage and Managed Identity. And since we're talking about an OCR system, where the main trigger will be the submission of an image for analysis, an HTTP Function fits perfectly. About the project architecture I organized the code structure in a clean and modular way, following a light DDD approach. /ocr-function-app ├── application/ │ └── UploadImageService.ts ├── domain/ │ └── IImageStorage.ts ├── infrastructure/ │ └── AzureBlobStorage.ts ├── HttpAddToBlob/ │ └── index.ts │ └── function.json ├── host.json ├── local.settings.json └── package.json The idea is for the Function to be just the entry point, delegating responsibilities to more specific layers. ⛏️ Setting Up the Azure Function Environment Before we start coding, we need to ensure that our Azure Function environment is ready to deploy and run correctly with Managed Identity authentication and Blob Storage integration. Create your Azure Function in the portal or via CLI: func init ocr-function-app --worker-runtime node --language typescript Create the HTTP trigger Function: func new --name HttpAddToBlob --template "HTTP trigger"

Apr 11, 2025 - 13:43
 0
Creating an OCR API with FaaS on Azure – Part 1: Architecture and Secure Upload

Recently, I've been working on an OCR system focused on reading digital medical prescriptions. The goal is simple: to allow healthcare professionals and pharmacies to automate the interpretation of medical prescriptions from images sent via API. All of this with security, scalability, and without the headache of credential management.

In this first article of the series, I'll show how I designed the architecture, the justification for using Azure Functions, and how I integrated with Blob Storage using Managed Identity. By the end, we'll have a functional endpoint for secure image upload. Shall we?

Why Azure Functions?

The choice of Azure Functions came naturally for several reasons:

  • Serverless: I don't need to worry about infrastructure.
  • Scalable: The system will handle many image uploads, so scaling on demand is essential.
  • Integrated with the Azure ecosystem: especially Blob Storage and Managed Identity.

And since we're talking about an OCR system, where the main trigger will be the submission of an image for analysis, an HTTP Function fits perfectly.

About the project architecture

I organized the code structure in a clean and modular way, following a light DDD approach.

/ocr-function-app
├── application/
│   └── UploadImageService.ts
├── domain/
│   └── IImageStorage.ts
├── infrastructure/
│   └── AzureBlobStorage.ts
├── HttpAddToBlob/
│   └── index.ts
│   └── function.json
├── host.json
├── local.settings.json
└── package.json

The idea is for the Function to be just the entry point, delegating responsibilities to more specific layers.

⛏️ Setting Up the Azure Function Environment

Before we start coding, we need to ensure that our Azure Function environment is ready to deploy and run correctly with Managed Identity authentication and Blob Storage integration.

  1. Create your Azure Function in the portal or via CLI:
func init ocr-function-app --worker-runtime node --language typescript
  1. Create the HTTP trigger Function:
func new --name HttpAddToBlob --template "HTTP trigger"