Introduction
Have you ever wanted easy access to structured European Medicines Agency (EMA) drug data? 💊Well, unless you are building a project that requires constant up to date medicine information I doubt that you’d even have any reason to think about it. 😁
However, I recently built an API that automates the extraction, transformation, and deployment of EMA drug data, making it accessible to developers, researchers, and businesses.
My name is Lyuben Sirakov, a Master of Pharmacy turned Software Engineer and in this post, I'll walk you through how I built, deployed my API on RapidAPI. Let’s get started! 🚀
Why Build an EMA API?
While looking for my next side project to build, I rediscovered RapidAPI—I'd forgotten I even had an account there—and decided to explore what APIs were available. When I checked the medicines/drugs section, I was surprised to find no API for data delivered by the EMA. The inspiration came quickly: build a proper API for medicines data. 💡
While the EMA provides a data hub, its downside is that it’s in Excel format and not readily consumable by applications.
My goal was to:
- Automate data retrieval from EMA’s public dataset. 🔁
- Convert it into JSON for easy use in applications. 📜
- Host the data in a MongoDB database for efficient querying. 📁
- Expose an API via Express.js to serve developers. 🖥️
- Deploy it on a cost-effective cloud provider (Railway). 🚅
- List it in RapidAPI and create subscription tiers based on usage. 💲
- Use the API as a side hustle to hopefully generate some revenue. 😁
Step 1: Automating EMA Data Retrieval
EMA provides drug-related data in Excel format. To keep the API up-to-date, I automated the process of:
- Downloading the latest EMA dataset from their public portal.
const EXCEL_URL = 'https://www.ema.europa.eu/en/documents/report/medicines-output-medicines-report_en.xlsx';
const EXCEL_DIR = path.join(__dirname, 'ema-data-excel');
const EXCEL_PATH = path.join(EXCEL_DIR, 'medicines_output_medicines_en.xlsx');
async function downloadExcelFile() {
try {
if (!fs.existsSync(EXCEL_DIR)) {
fs.mkdirSync(EXCEL_DIR, { recursive: true });
}
console.log('Downloading Excel file from EMA website...');
const response = await axios({
method: 'get',
url: EXCEL_URL,
responseType: 'arraybuffer'
});
fs.writeFileSync(EXCEL_PATH, response.data);
console.log('Excel file downloaded successfully to:', EXCEL_PATH);
} catch (error) {
console.error('Error downloading Excel file:', error.message);
throw error;
}
}
2.Parsing the Excel file into JSON using xlsx
in Node.js.
3.Cleaning and structuring the data into a consistent format.
Here’s a simplified script for parsing the Excel file:
const xlsx = require("xlsx");
const fs = require("fs");
const filePath = "medicines_output_medicines_en.xlsx";
const workbook = xlsx.readFile(filePath);
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const jsonData = xlsx.utils.sheet_to_json(sheet);
fs.writeFileSync("ema_medicines.json", JSON.stringify(jsonData, null, 2));
console.log("Data extracted successfully!");
Step 2: Storing the Data in MongoDB
To efficiently serve the data, I set up a MongoDB Atlas cluster and wrote a script to upload the extracted JSON data:
const mongoose = require("mongoose");
const fs = require("fs");
mongoose.connect("mongodb+srv://mongodb_url", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const MedicineSchema = new mongoose.Schema({
category: {
type: String,
default: '',
required: true,
},
medicineName: {
type: String,
default: '',
required: true,
},
emaProductNumber: {
type: String,
default: '',
required: true,
},
medicineStatus: {
type: String,
default: '',
required: true,
},
inn: {
type: String,
default: '',
required: true,
},
//...ect.
});
const Medicine = mongoose.model("Medicine", MedicineSchema );
const jsonData = JSON.parse(fs.readFileSync("ema_medicines.json"));
Medicine.insertMany(jsonData)
.then(() => console.log("Data uploaded to MongoDB!"))
.catch((err) => console.error(err));
Step 3: Building an Express.js API
Here’s the simplified version of the Express.js server I built to expose endpoints for querying drug data:
const express = require("express");
const mongoose = require("mongoose");
const app = express();
const PORT = process.env.PORT || 3000;
mongoose.connect("mongodb+srv://mongodb_url", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const Medicine = mongoose.model("Medicine", new mongoose.Schema({ name: String, activeSubstance: String }));
app.get("/api/medicines", async (req, res) => {
const medicines = await Medicine.find();
res.json(medicines);
});
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Step 4: Deploying the API on Railway
I chose Railway for hosting due to its free tier and easy integration with MongoDB. Deployment steps:
- I pushed my project to GitHub.
- Connected GitHub to Railway.
- Added environment variables (MongoDB URL, API keys).
-
Deployed the app
Step 5: Publishing the API on RapidAPI
I listed the API on RapidAPI with different pricing tiers.
- Basic Tier: Limited requests for testing (10K requests).
- Pro Plan ($15/month): 500K requests.
- Ultra Plan ($30/month): 1M requests.
- Mega Plan ($135/month): 5M requests.
👉 Check out the API here: https://rapidapi.com/LubenSirakov/api/ema-medicines-data-api
Final Thoughts
In my day-to-day job as a front-end dev, I found it quite refreshing to do some back-end programming. This was a fun project that combined data automation, backend and API development. If you’re looking for an easy way to access EMA drug data, feel free to try my API!
📌 Interested? Try it here: https://rapidapi.com/LubenSirakov/api/ema-medicines-data-api
📌 Let’s connect! Lyuben Sirakov
I'd love to hear your feedback—please share any features you'd like to see, ideas you have, or constructive criticism. What would you like to see next? 🚀
#api #nodejs #expressjs #mongodb #webdev #backend #railway #rapidapi #ema #medicine
Top comments (0)