JavaScript Examples
Complete JavaScript/TypeScript examples for Node.js and browsers.
Basic usage
Using fetch (browser & Node.js 18+)
const API_KEY = process.env.WIKIREST_API_KEY;
const BASE_URL = "https://api.wikirest.com/v1";
async function search(query, limit = 10) {
const params = new URLSearchParams({ q: query, limit: String(limit) });
const response = await fetch(`${BASE_URL}/search?${params}`, {
headers: { "X-API-Key": API_KEY }
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
return response.json();
}
// Example usage
const results = await search("machine learning", 5);
results.hits.forEach(hit => {
console.log(`📄 ${hit.title}`);
console.log(` ${hit.text.slice(0, 150)}...`);
}); Get specific chunk
async function getChunk(chunkId) {
const response = await fetch(`${BASE_URL}/chunk/${chunkId}`, {
headers: { "X-API-Key": API_KEY }
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}
const chunk = await getChunk("12345_3");
console.log(`Title: ${chunk.title}`);
console.log(`Section: ${chunk.section}`);
console.log(`Text: ${chunk.text}`); Get full page
async function getPage(pageId, format = "chunks") {
const params = new URLSearchParams({ format });
const response = await fetch(`${BASE_URL}/page/${pageId}?${params}`, {
headers: { "X-API-Key": API_KEY }
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}
// Get as chunks
const page = await getPage(12345, "chunks");
console.log(`Title: ${page.title}`);
console.log(`Total chunks: ${page.total_chunks}`);
// Get as concatenated text
const pageText = await getPage(12345, "concat");
console.log(`Word count: ${pageText.word_count}`); TypeScript
// types.ts
export interface SearchHit {
id: string;
page_id: number;
title: string;
section: string;
text: string;
chunk_index: number;
url: string;
_formatted?: {
text: string;
};
}
export interface SearchResponse {
hits: SearchHit[];
query: string;
processingTimeMs: number;
estimatedTotalHits: number;
}
export interface Chunk {
id: string;
page_id: number;
title: string;
section: string;
text: string;
chunk_index: number;
url: string;
word_count: number;
modified: string;
}
export interface Page {
page_id: number;
title: string;
url: string;
extract: string;
modified: string;
chunks?: Array<{
id: string;
section: string;
text: string;
chunk_index: number;
}>;
total_chunks?: number;
text?: string;
word_count?: number;
}
// client.ts
export class WikiRestClient {
private apiKey: string;
private baseUrl: string;
constructor(apiKey: string, baseUrl = "https://api.wikirest.com/v1") {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
private async request(endpoint: string, params?: Record): Promise {
const url = new URL(`${this.baseUrl}${endpoint}`);
if (params) {
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
}
const response = await fetch(url.toString(), {
headers: { "X-API-Key": this.apiKey }
});
if (!response.ok) {
const error = await response.json().catch(() => ({ message: "Unknown error" }));
throw new Error(`HTTP ${response.status}: ${error.message}`);
}
return response.json();
}
async search(query: string, options: { limit?: number; offset?: number } = {}): Promise {
return this.request("/search", {
q: query,
limit: String(options.limit ?? 10),
offset: String(options.offset ?? 0)
});
}
async getChunk(chunkId: string): Promise {
return this.request(`/chunk/${chunkId}`);
}
async getPage(pageId: number, format: "chunks" | "concat" = "chunks"): Promise {
return this.request(`/page/${pageId}`, { format });
}
}
// Usage
const client = new WikiRestClient(process.env.WIKIREST_API_KEY!);
const results = await client.search("quantum computing", { limit: 5 }); Node.js with axios
import axios from "axios";
const client = axios.create({
baseURL: "https://api.wikirest.com/v1",
headers: { "X-API-Key": process.env.WIKIREST_API_KEY },
timeout: 30000
});
// Add response interceptor for error handling
client.interceptors.response.use(
response => response,
async error => {
if (error.response?.status === 429) {
const retryAfter = parseInt(error.response.headers["retry-after"] || "60");
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
return client.request(error.config);
}
throw error;
}
);
// Search function
async function search(query, limit = 10) {
const { data } = await client.get("/search", {
params: { q: query, limit }
});
return data;
}
// Example
const results = await search("neural networks", 5);
console.log(`Found ${results.estimatedTotalHits} results`); Browser usage
<!DOCTYPE html>
<html>
<head>
<title>WikiRest Search</title>
</head>
<body>
<input type="text" id="query" placeholder="Search Wikipedia...">
<button onclick="search()">Search</button>
<div id="results"></div>
<script>
// Note: Never expose API keys in client-side code for production!
// Use a backend proxy instead
const API_KEY = "your_key_here"; // Use backend proxy in production
async function search() {
const query = document.getElementById("query").value;
const resultsDiv = document.getElementById("results");
try {
const response = await fetch(
`https://api.wikirest.com/v1/search?q=${encodeURIComponent(query)}&limit=10`,
{ headers: { "X-API-Key": API_KEY } }
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
resultsDiv.innerHTML = data.hits.map(hit => `
<div class="result">
<h3><a href="${hit.url}" target="_blank">${hit.title}</a></h3>
<p>${hit._formatted?.text || hit.text}</p>
</div>
`).join("");
} catch (error) {
resultsDiv.innerHTML = `<p class="error">Error: ${error.message}</p>`;
}
}
</script>
</body>
</html> React hook
import { useState, useCallback } from "react";
interface SearchResult {
id: string;
title: string;
text: string;
url: string;
}
interface UseWikiSearchResult {
results: SearchResult[];
loading: boolean;
error: string | null;
search: (query: string) => Promise;
}
export function useWikiSearch(apiKey: string): UseWikiSearchResult {
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const search = useCallback(async (query: string) => {
if (!query.trim()) {
setResults([]);
return;
}
setLoading(true);
setError(null);
try {
const response = await fetch(
`https://api.wikirest.com/v1/search?q=${encodeURIComponent(query)}&limit=10`,
{ headers: { "X-API-Key": apiKey } }
);
if (!response.ok) {
throw new Error(`Search failed: ${response.status}`);
}
const data = await response.json();
setResults(data.hits);
} catch (err) {
setError(err instanceof Error ? err.message : "Unknown error");
setResults([]);
} finally {
setLoading(false);
}
}, [apiKey]);
return { results, loading, error, search };
}
// Usage in component
function SearchComponent() {
const { results, loading, error, search } = useWikiSearch("YOUR_API_KEY");
const [query, setQuery] = useState("");
return (
setQuery(e.target.value)}
onKeyPress={e => e.key === "Enter" && search(query)}
placeholder="Search Wikipedia..."
/>
{error && {error}
}
{results.map(result => (
-
{result.title}
{result.text.slice(0, 200)}...
))}
);
} Error handling
async function searchWithRetry(query, maxRetries = 3) {
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(
`https://api.wikirest.com/v1/search?q=${encodeURIComponent(query)}&limit=10`,
{
headers: { "X-API-Key": process.env.WIKIREST_API_KEY },
signal: AbortSignal.timeout(30000) // 30s timeout
}
);
if (response.ok) {
return response.json();
}
if (response.status === 429) {
// Rate limited
const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
const wait = Math.min(retryAfter, Math.pow(2, attempt) * 1000);
console.log(`Rate limited. Waiting ${wait}ms...`);
await new Promise(r => setTimeout(r, wait));
continue;
}
if (response.status >= 500) {
// Server error - retry
const wait = Math.pow(2, attempt) * 1000;
console.log(`Server error. Retrying in ${wait}ms...`);
await new Promise(r => setTimeout(r, wait));
continue;
}
// Client error - don't retry
const error = await response.json();
throw new Error(`${response.status}: ${error.message}`);
} catch (err) {
lastError = err;
if (err.name === "AbortError") {
console.log("Request timed out. Retrying...");
continue;
}
throw err;
}
}
throw lastError || new Error("Max retries exceeded");
} Streaming results
// For large result sets, process as they arrive
async function* searchGenerator(query, totalResults = 100) {
let offset = 0;
const limit = 50;
while (offset < totalResults) {
const response = await fetch(
`https://api.wikirest.com/v1/search?q=${encodeURIComponent(query)}&limit=${limit}&offset=${offset}`,
{ headers: { "X-API-Key": process.env.WIKIREST_API_KEY } }
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
for (const hit of data.hits) {
yield hit;
}
if (data.hits.length < limit) break;
offset += limit;
}
}
// Usage
for await (const hit of searchGenerator("artificial intelligence", 100)) {
console.log(hit.title);
// Process each result as it arrives
}