慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

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)
五分钟内构建临床试验搜索应用——临床试验API教程
Rahul Ban · 2026-05-24 · via DEV Community

Rahul Ban

吾辈所筑者何?

五分钟之内,尔将筑一简易网应用,使用户可按症候与阶段搜临床试验,以卡式显其果,并分页览之。 临床试验API 者,乃 ClinicalTrials.gov 之 REST API 也,为开发者所便。其予汝结构化之资格标准(解析为年龄、性别、病症、化验值等类,无需正则),可依纬经度寻地理半径,新试验至则 HTTP webhook 促警,以游标分页,并集统计之数。免费版无需信用卡。试验逾四十八万,遍二百二十国,日更自 FDA。一 API 而成之。汝需知 HTML/JavaScript 基本之识,并得 RapidAPI 免费之户。

第一步:获取您的API密钥(三十秒内)

  1. 往矣https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api
  2. 于免费之契,点"订阅"(无需信用卡)
  3. 自仪表盘复制汝之X-RapidAPI-Key

善哉。汝可呼API矣。

第二步:行首次 API 之唤

启尔终端,行此 curl 命令(易尔 API_KEY):

curl --request GET \
  --url 'https://clinical-trials-api.p.rapidapi.com/v1/trials/search?query=breast+cancer&phase=Phase+2&status=Recruiting&limit=3' \
  --header 'X-RapidAPI-Key: YOUR_API_KEY'

入全屏模式 出全屏模式

当见若此:

{
  "success": true,
  "data": [
    {
      "nct_id": "NCT04589845",
      "title": "Atezolizumab and Chemotherapy for Triple-Negative Breast Cancer",
      "brief_summary": "This phase II trial studies how well atezolizumab works with chemotherapy...",
      "condition": "Breast Cancer",
      "phase": "Phase 2",
      "status": "Recruiting",
      "enrollment_count": 280,
      "last_updated": "2026-05-15",
      "locations": [
        {
          "facility": "Dana-Farber Cancer Institute",
          "city": "Boston",
          "state": "MA",
          "country": "United States"
        }
      ]
    }
  ],
  "pagination": {
    "total": 847,
    "limit": 3,
    "next_cursor": "eyJvZmZzZXQiOjN9",
    "has_more": true
  }
}

入全屏模式 出全屏模式

是八百四十七匹配之试,以净洁之 JSON 返,具内置分页。无刮取,无解析,无管流。

第三步:建试搜之应用

创一HTML文件index.html)并粘贴此代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Clinical Trial Search</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 800px; margin: 40px auto; padding: 0 20px; background: #f5f5f5; }
        h1 { color: #1a1a2e; }
        .search-box { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
        input, select, button { padding: 10px 15px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px; }
        input { flex: 1; min-width: 200px; }
        button { background: #1a56db; color: white; border: none; cursor: pointer; font-weight: 600; }
        button:hover { background: #1647b8; }
        .trial-card { background: white; border-radius: 8px; padding: 20px; margin-bottom: 15px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
        .trial-card h3 { margin: 0 0 8px 0; color: #1a1a2e; font-size: 16px; }
        .trial-meta { display: flex; gap: 15px; font-size: 13px; color: #666; margin-bottom: 8px; flex-wrap: wrap; }
        .badge { padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 600; }
        .badge-recruiting { background: #d4edda; color: #155724; }
        .badge-phase { background: #cce5ff; color: #004085; }
        .summary { font-size: 14px; color: #444; line-height: 1.5; }
        .pagination { display: flex; gap: 10px; align-items: center; margin-top: 20px; justify-content: center; }
        .loading { text-align: center; padding: 40px; color: #666; }
        .error { text-align: center; padding: 20px; color: #dc3545; background: #f8d7da; border-radius: 8px; }
        .nct { color: #1a56db; font-family: monospace; font-size: 14px; }
        .location { font-size: 12px; color: #888; margin-top: 6px; }
    </style>
</head>
<body>
    <h1>Clinical Trial Search</h1>
    <p style="color: #666; margin-bottom: 20px;">Powered by <a href="https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api">Clinical Trials API</a> -- 480K+ FDA trials, free tier, no credit card.</p>

    <div class="search-box">
        <input type="text" id="query" placeholder="Search condition or keyword (e.g., breast cancer)" value="breast cancer">
        <select id="phase">
            <option value="">All Phases</option>
            <option value="Phase 1">Phase 1</option>
            <option value="Phase 2" selected>Phase 2</option>
            <option value="Phase 3">Phase 3</option>
            <option value="Phase 4">Phase 4</option>
        </select>
        <select id="status">
            <option value="">All Statuses</option>
            <option value="Recruiting" selected>Recruiting</option>
            <option value="Not yet recruiting">Not Yet Recruiting</option>
            <option value="Active not recruiting">Active, Not Recruiting</option>
            <option value="Completed">Completed</option>
        </select>
        <button onclick="searchTrials()">Search</button>
    </div>

    <div id="results"></div>

    <script>
        const API_KEY = 'YOUR_RAPIDAPI_KEY'; // Replace with your key
        const BASE_URL = 'https://clinical-trials-api.p.rapidapi.com';

        let currentCursor = null;
        let currentQuery = null;

        async function searchTrials(cursor = null) {
            const query = document.getElementById('query').value;
            const phase = document.getElementById('phase').value;
            const status = document.getElementById('status').value;

            const params = new URLSearchParams({ query, limit: '5' });
            if (phase) params.append('phase', phase);
            if (status) params.append('status', status);
            if (cursor) params.append('cursor', cursor);

            const resultsDiv = document.getElementById('results');
            resultsDiv.innerHTML = '<div class="loading">Searching 480K+ clinical trials...</div>';

            try {
                const r = await fetch(`${BASE_URL}/v1/trials/search?${params}`, {
                    headers: { 'X-RapidAPI-Key': API_KEY }
                });

                if (r.status === 401) {
                    resultsDiv.innerHTML = '<div class="error">Invalid API key. Get your free key at <a href="https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api">rapidapi.com/clinical-trials-api</a></div>';
                    return;
                }

                if (!r.ok) {
                    resultsDiv.innerHTML = `<div class="error">API error: HTTP ${r.status}</div>`;
                    return;
                }

                const body = await r.json();
                if (!body.success) {
                    resultsDiv.innerHTML = `<div class="error">${body.error?.message || 'Unknown error'}</div>`;
                    return;
                }

                currentCursor = cursor;
                currentQuery = { query, phase, status };
                renderResults(body);

            } catch (e) {
                resultsDiv.innerHTML = `<div class="error">Network error: ${e.message}</div>`;
            }
        }

        function renderResults(body) {
            const resultsDiv = document.getElementById('results');
            const pagination = body.pagination;

            let html = `<p style="color: #666; margin-bottom: 15px;">Found <strong>${pagination.total.toLocaleString()}</strong> trials. Showing ${(currentCursor ? 'next page' : 'first')} ${body.data.length} results.</p>`;

            body.data.forEach(trial => {
                const loc = trial.locations && trial.locations[0] ? `${trial.locations[0].facility}, ${trial.locations[0].city}, ${trial.locations[0].state}` : '';
                html += `
                    <div class="trial-card">
                        <h3>${trial.title}</h3>
                        <div class="trial-meta">
                            <span class="nct">${trial.nct_id}</span>
                            <span class="badge badge-phase">${trial.phase}</span>
                            <span class="badge badge-recruiting">${trial.status}</span>
                            ${trial.enrollment_count ? `<span>${trial.enrollment_count} participants</span>` : ''}
                        </div>
                        <p class="summary">${(trial.brief_summary || '').substring(0, 200)}${(trial.brief_summary || '').length > 200 ? '...' : ''}</p>
                        ${loc ? `<p class="location">${loc}</p>` : ''}
                    </div>
                `;
            });

            html += '<div class="pagination">';

            if (currentCursor) {
                html += `<button onclick="searchTrials(null)">First Page</button>`;
            }

            if (pagination.has_more) {
                html += `<button onclick="loadNextPage('${pagination.next_cursor}')">Next Page (${pagination.total - (currentCursor ? parseInt(currentCursor.match(/\d+/)?.[0] || 0) : body.data.length)} remaining)</button>`;
            } else if (body.data.length > 0) {
                html += '<span style="color: #666;">All results loaded.</span>';
            }

            html += '</div>';
            resultsDiv.innerHTML = html;
        }

        function loadNextPage(cursor) {
            document.getElementById('query').value = currentQuery.query;
            document.getElementById('phase').value = currentQuery.phase;
            document.getElementById('status').value = currentQuery.status;
            searchTrials(cursor);
        }

        // Search on load
        searchTrials();
    </script>
</body>
</html>

入全景模式 出全屏模式

第四步:运行之

  1. 更易YOUR_RAPIDAPI_KEY在线之七十位,以汝之实际API密钥。
  2. index.html于汝之浏览器(但双击此文件)
  3. 汝有可用之临床试验搜寻之应用

试以"Alzheimer"(阿尔茨海默)、"diabetes"(糖尿病)为钥,或任其默认之"breast cancer"(乳腺癌)——秒息间,真FDA试验之数据自现矣

其后何为?

  • 增地理半径搜寻之端点(/v1/trials/nearby),以HTML5地理解析,建"近我之试验"之功能
  • 增结构化资格显示,以调用/v1/trials/{nct_id}/eligibility 俟用户点击试用之卡(专业版:十九元/月)
  • 乃设网钩警报于 POST /v1/alerts,俾得新试用者合乎用户所存之检索标准时得闻之
  • 部署于 Vercel、Netlify 或 GitHub Pages,以示实演
  • 以 Tailwind CSS 为之饰,以显专业之姿

API

速订于RapidAPI - 免费套餐,无需信用卡.


若尔以是API成物,请标吾名——吾愿观尔所创。疑问投于注脚,吾当答之。