인셔셔RSS 관심 있는 블로그, 뉴스, 기술 정보를 효율적으로 추적하고 읽으세요
원문 읽기 InertiaRSS에서 열기

추천 피드

Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
M
MIT News - Artificial intelligence
博客园 - 叶小钗
MyScale Blog
MyScale Blog
V
Visual Studio Blog
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
I
InfoQ
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
Jina AI
Jina AI
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Blog — PlanetScale
Blog — PlanetScale
Last Week in AI
Last Week in AI
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
博客园 - Franky

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
나는 2주 동안 Clinical Trials API를 어떻게 구축했는지 - 공개 데이터에서 RapidAPI까지
Rahul Ban · 2026-05-25 · via DEV Community

ClinicalTrials.gov - 미국 정부의 FDA 임상 시험 등록부 -는 하루에 업데이트되는 공공 도메인 데이터로 480,000개 이상의 연구를 게시합니다. 이는 의료 분야에서 가장 가치 있는 데이터셋 중 하나입니다. 제약사, CRO, 헬스테크 스타트업, 학계 연구자 모두 이 데이터를 프로그래밍적으로 필요로 합니다.

하지만 공식 ClinicalTrials.gov API v2는 인간 연구자들을 위해 만들어진 검색 엔진을 둘러싼 REST 래퍼입니다. 구조화된 자격 요건 분석이 없습니다. 지리적 반경 검색이 없습니다. 웹훅 알림이 없습니다. 페이지네이션이 페이지 중간에 매개변수를 변경하면 중단됩니다. 기본 키워드 검색을 넘어서는 무언가를 만들고 싶다면 웹사이트를 스크래핑하거나 2GB 텍스트 파일을 다운로드하거나 엔터프라이즈 공급업체에 $500+/월을 지불하게 됩니다.

그래서 Clinical Trials API를 구축했습니다 - ClinicalTrials.gov 위에 올라간 올바른 REST 레이어로, 구조화된 자격 요건, 지역 검색, 웹훅 알림이 있습니다. 이렇게 진행되었습니다.

스택

  • 런타임: Python 워커 (Pyodide, Redux 메모리 스냅샷)
  • 배포: Wrangler CLI -> 전 세계 330개 이상의 엣지 위치
  • 백엔드 데이터: ClinicalTrials.gov API v2 (공공 도메인, 인증 필요 없음)
  • 마켓플레이스 & 청구: RapidAPI
  • 가격: 무료 / $49/월 (Pro) / $199/월 (Ultra)
  • 평균 응답 시간: 350-500ms 온, ~1초 차가운 시작

나가 만든 것

10 개수의 엔드포인트를 4개의 기능 그룹으로 나누어 있습니다:

엔드포인트 설명 레벨
GET /v1/trials/search 전체 텍스트 + 필드 기반 검색, 커서 기반 페이지네이션 무료
GET /v1/trials/{nct_id} 결과, 위치, 참조와 함께 완전한 시험 세부 정보 무료
GET /v1/trials/nearby 위도/경도를 이용한 지리적 반경 검색, 거리 순 정렬 무료
GET /v1/stats 단계별, 상태별, 후원자별, 연구 유형별 집계 통계 무료
GET /v1/conditions 의료 상태 자동 완성 브라우저 무료
GET /v1/health 건강 검사, 인증 필요 없음 무료
GET /v1/trials/{nct_id}/eligibility 구조화된 합격 기준 해석 프로
GET /v1/alerts 활성 웹훅 알림 목록 프로
POST /v1/alerts 새로운 시험을 위한 웹훅 알림 생성 프로
DELETE /v1/alerts/{alert_id} 웹훅 알림 삭제 프로

어려운 부분들

도전 1: 자유형 자격 요건 분석

이것이 가장 어려운 기술적 문제였습니다. ClinicalTrials.gov은 자격 요건을 자유형 텍스트로 저장합니다 - 종종 구조가 전혀 없는 단일 단락이나 목록으로 구성됩니다:

"포함 기준: 조직학적으로 확인된 삼중 부정상 유방암. 연령 >= 18세. ECOG 기능 상태 0 또는 1. 적절한 혈액학적 및 종기 기능. 전이성 유방암에 대한 이전 전체 체계 치료가 없음. 제외 기준: 유방암에 대한 이전 면역 치료. 활성 자가면역 질환으로 인한 전체 체계 치료가 필요함. 치료되지 않은 또는 증상이 있는 중추 신경계 전이. 임신 또는 수유 중."

이것을 구조화되고 기계가 읽을 수 있는 기준 객체로 파싱해야 했는데, 환자 일치 알고리즘이 실제로 사용할 수 있었어요:

{
  "inclusion_criteria": [
    {"category": "Age", "text": "Age >= 18 years", "criterion": "18 years and older"},
    {"category": "Condition", "text": "Histologically confirmed triple-negative breast cancer", "criterion": "Triple-negative breast cancer confirmed by histology"},
    {"category": "Performance Status", "text": "ECOG performance status 0 or 1", "criterion": "ECOG 0-1"}
  ],
  "exclusion_criteria": [
    {"category": "Prior Treatment", "text": "Prior immunotherapy for breast cancer", "criterion": "No prior checkpoint inhibitor therapy"}
  ]
}

전체 화면 모드로 전환 전체 화면 모드 종료

제 접근 방식: 히ュ리스틱 NLP 파이프라인. 먼저, 원시 텍스트를 별점, 번호 목록, 줄 바꿈 및 문장 경계와 일치하는 정규식 패턴을 사용하여 후보 기준으로 분할합니다. 그런 다음 키워드 일치 및 규칙 기반 논리를 사용하여 각 후보를 8개 카테고리(나이, 성별, 상태, 실험실 값, 이전 치료, 성능 상태, 기관 기능, 기타) 중 하나로 분류합니다. 마지막으로 정규화된 간결한 형태를 생성합니다.

정확도는 약 80-85%입니다. 나머지 15-20%는 원본 텍스트를 보존한 "기타" 카테고리를 받습니다. 올바른 ML 모델은 더 잘할 것입니다. 하지만 v1을 출시하고 피드백에 따라 반복하고 싶었습니다. 구조화된 파싱은 Pro 티어($49/월)에 있습니다. 이는 유료 플랜을 정당화하는 핵심 가치가 되기 때문입니다.

도전 과제 2: 지리적 검색 (지오코딩 예산 없이)

ClinicalTrials.gov은 시설 주소(이름, 도시, 주, 국가)를 목록에 올리지만 위도/경도 좌표를 제공하지 않습니다. 지리적 반경 검색을 구축하기 위해 모든 시설의 지오코딩이 필요합니다.

문제점: 데이터베이스에는 약 500,000개의 고유한 시설 주소가 있습니다. 상업용 지오코딩 API는 1,000회 검색당 비용을 청구합니다. 무료 지오코딩 API는 엄격한 요청 제한(~1 요청/초)이 있습니다.

제 접근 방식: 사전 구축된 검색 테이블. 3일 동안 파이썬 스크립트를 실행하여 모든 주소를 무료 지오코딩 API에 대조하여 지오코딩했으며, 요청 제한이 적용되었습니다. 결과 테이블은 시설 주소를 위도/경도에 매핑하며, 작업자의 모듈 수준 메모리에 로드됩니다. /v1/trials/nearby을 쿼리할 때 작업자:

  1. ClinicalTrials.gov에서 필터링 조건에 맞는 시험을 검색합니다
  2. 메모리 테이블에서 각 시설의 좌표를 확인합니다
  3. 검색 중심지에서 해밍스타인 거리를 계산합니다
  4. 거리순으로 정렬하여 결과를 반환합니다

테이블은 메모리에 ~20MB 크기이지만, 활성화된 시험만을 포함하고 있습니다. 근처 검색에 대한 응답 시간은 업스트림 API 호출과 거리 계산을 포함하여 400-600ms입니다. 즉각적이지는 않지만, 실시간으로 지오코딩을 할 때보다 훨씬 빠릅니다.

도전 3: 가격 책정 - 실제로 유용한 무료 계층과 수익

영원한 인디 개발자의 딜레마. 무료 티어를 유저를 유인할 만큼 유용하지만, 전환을 유도할 만큼 제한적일 수 있도록 어떻게 만들 것인가?

내 접근 방식: 데이터 접근을 무료로 제공하고, 가치 추가 처리에 대해 유료화한다.

무료 계층에는 10개의 엔드포인트 중 7개가 포함됩니다. 트라이얼을 검색하고, 세부 정보를 얻고, 지리적 검색을 하고, 조건을 탐색하고, 집계 통계를 가져오는 등 실제 프로토타입을 만들기 위해 필요한 모든 기능을 제공합니다. 하루에 100개의 요청, 3개의 저장된 웹훅 경고. 신용카드 없이, 만료 없이. 무료 계층은 "아하 순간"을 제공해야 합니다: "와, 한 번의 API 호출로 480K 트라이얼을 쿼리했다."

프로 티어($49/월)는 실제 엔지니어링 시간을 절약하는 기능을 해제합니다: 구조화된 자격 요건 파싱(정규식 파서를 직접 만드는 대신)과 확장된 웹훅 알림(25개 대신 3개, 6시간 간격 체크 대신 일일 체크).

얄트라($199/월)는 임상 시험 데이터가 임무 중요한 회사를 위해 제공됩니다. 더 높은 요청 제한, 무제한 알림, 우선 지원, 전용 SLA.

변환 가설: 무료 티어 사용자가 하루 100 요청 제한에 도달하거나 자격 요건 분석이 필요하며, $49/월은 개발자 시간의 한 시간보다 저렴합니다.

나는 다르게 할 것입니다

  1. 지오코딩 전략. 무료 지오코딩 API에 대해 3일간 비율 제한을 적용하는 것은 어리석았습니다. $50를 내고 상업 지오코딩 서비스를 구매하고 2시간 안에 끝낸을 수 있어야 했습니다. "무료로 하는 것이 돈을 아끼는" 본능은 인디 개발자들에게 강하지만, 당신의 시간은 더 가치가 높습니다.

  2. API 설계 - 합격 여부 엔드포인트를 분리 vs. 내장. 저는 분리된 엔드포인트를 선택했습니다 (/v1/trials/{nct_id}/eligibility)는 파싱이 처리 시간에 약 200ms를 추가하기 때문이며, 무료 티어 사용자는 사용할 수 없는 기능의 지연 비용을 부담해서는 안 됩니다. 돌이켜보면, 시험 세부 정보 엔드포인트에서 파싱된 자격 요건을 직접 반환하는 것이 더 깔끔했을 것입니다. 개발자들은 하나의 요청을 기대하지만, 두 번의 요청을 기대하지는 않습니다. 저는 v2에서 이들을 통합할 수도 있습니다.

숫자 (지금까지)

최근 출시됨. 실제 숫자는 곧 나올 예정.

미터릭
구독자 0 (일 1)
API 호출 처리 0 (일 1)
수익 (MRR) $0 (일 1)
운영 시간 99.9% (목표)
평균 응답 시간 350-500ms
인프라 비용 $0 (CF 워커 무료 계층)

30일 안에 실제 숫자로 업데이트하겠습니다.

시도해보세요

https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api - 무료 계층, 신용카드 없음. API 키를 얻고 첫 번째 호출을 하는 데 30초 걸림.


건강 기술 제품을 개발하고 임상 시험 데이터가 필요하시다면, 이를 진정으로 유용하게 만들 수 있는 종결 지점(endpoints)이 무엇인지 들려주시겠어요. 빠르게 배송해요 - 만약 아직 존재하지 않는 것을 필요하시다면, 알려주시면 48시간 안에 배포할 가능성이 높아요.