openalex-client
Version:
TypeScript SDK for OpenAlex academic database API
298 lines (221 loc) • 6.97 kB
Markdown
# OpenAlex client
A comprehensive TypeScript client for the [OpenAlex](https://openalex.org) academic database API. This SDK provides type-safe access to scholarly works, authors, institutions, sources, and concepts.
## Features
- 🎯 **Full TypeScript support** with comprehensive type definitions
- 🔄 **Complete API coverage** for all OpenAlex entities
- ⚡ **Built-in retry logic** with exponential backoff
- 🌐 **Native fetch API** - no external HTTP dependencies
- 📄 **Pagination support** with async generators
- 🔍 **Advanced search capabilities** and filters
- 🏗️ **Modular architecture** with service-based organization
- ⏱️ **Request timeout and abort support**
## Requirements
- Node.js 18+ (for native fetch support)
- TypeScript 5+ (for development)
## Installation
```bash
npm install openalex-client
```
## Quick Start
```typescript
import { OpenAlex } from "openalex-client";
// Initialize the SDK
const openAlex = new OpenAlex({
userAgent: "MyApp/1.0.0 (mailto:your-email@example.com)",
});
// Search for works
const works = await openAlex.works.list({
search: "artificial intelligence",
per_page: 10,
});
console.log(`Found ${works.meta.count} works`);
// Get a specific work by DOI
const work = await openAlex.works.getByDoi("10.1038/nature12373");
console.log(work.title);
// Get author information
const author = await openAlex.authors.get("A2208157607");
console.log(`${author.display_name} has ${author.works_count} works`);
```
## Configuration
```typescript
const openAlex = new OpenAlex({
baseURL: "https://api.openalex.org", // API base URL
userAgent: "MyApp/1.0.0", // Required: Your app identifier
timeout: 30000, // Request timeout in ms
retries: 3, // Number of retry attempts
retryDelay: 1000, // Base delay between retries
});
```
## Core Services
### Works Service
```typescript
// Search works
const works = await openAlex.works.list({
search: "machine learning",
filter: {
publication_year: "2023",
"open_access.is_oa": true,
},
sort: "cited_by_count:desc",
});
// Get works by author
const authorWorks = await openAlex.works.getByAuthor("A2208157607");
// Get citations
const citations = await openAlex.works.getCitedBy("W2741809807");
// Get open access works
const oaWorks = await openAlex.works.getOpenAccess({
filter: { publication_year: "2023" },
});
```
### Authors Service
```typescript
// Get author by ORCID
const author = await openAlex.authors.getByOrcid("0000-0002-1825-0097");
// Get authors from institution
const institutionAuthors = await openAlex.authors.getByInstitution("I27837315");
// Get highly cited authors
const topAuthors = await openAlex.authors.getHighlyCited({ per_page: 50 });
// Get co-authors
const coAuthors = await openAlex.authors.getCoAuthors("A2208157607");
```
### Institutions Service
```typescript
// Get institution by ROR
const institution = await openAlex.institutions.getByRor("05dxps055");
// Get institutions by country
const usInstitutions = await openAlex.institutions.getByCountry("US");
// Get university-type institutions
const universities = await openAlex.institutions.getUniversities();
// Get institution's works
const institutionWorks = await openAlex.institutions.getWorks("I27837315");
```
### Sources Service
```typescript
// Get source by ISSN
const journal = await openAlex.sources.getByIssn("0028-0836");
// Get open access journals
const oaJournals = await openAlex.sources.getOpenAccess();
// Get journals in DOAJ
const doajJournals = await openAlex.sources.getDoajSources();
// Get sources by publisher
const springerJournals =
await openAlex.sources.getByPublisher("Springer Nature");
```
### Concepts Service
```typescript
// Get concept hierarchy
const hierarchy = await openAlex.concepts.getHierarchy("C41008148");
// Get works related to concept
const conceptWorks = await openAlex.concepts.getWorks("C41008148");
// Get top-level concepts
const topConcepts = await openAlex.concepts.getTopLevel();
// Find similar concepts
const similar = await openAlex.concepts.findSimilar(
"machine learning algorithms",
);
```
## Advanced Usage
### Pagination
```typescript
// Using async generator for automatic pagination
for await (const work of openAlex.works.paginate({
search: "climate change",
})) {
console.log(work.title);
}
// Manual pagination
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await openAlex.works.list({
search: "quantum computing",
page,
per_page: 100,
});
// Process works
response.results.forEach((work) => {
console.log(work.title);
});
hasMore = response.results.length === 100;
page++;
}
```
### Complex Filtering
```typescript
const works = await openAlex.works.list({
filter: {
"authorships.institutions.country_code": "US",
publication_year: "2020-2023",
"open_access.is_oa": true,
cited_by_count: ">100",
"concepts.id": "C41008148", // Computer Science
},
sort: "publication_date:desc",
});
```
### Grouping and Aggregation
```typescript
const worksByYear = await openAlex.works.list({
group_by: "publication_year",
filter: {
"concepts.id": "C41008148",
},
});
console.log(worksByYear.group_by); // Aggregated results by year
```
### Field Selection
```typescript
// Select only specific fields to reduce response size
const works = await openAlex.works.list({
select: "id,title,publication_year,cited_by_count",
search: "artificial intelligence",
});
```
## Error Handling
```typescript
try {
const work = await openAlex.works.getByDoi("invalid-doi");
} catch (error) {
if (error.status_code === 404) {
console.log("Work not found");
} else {
console.error("API Error:", error.message);
}
}
```
## Rate Limiting and Best Practices
- **Use a descriptive User-Agent**: Include your email for faster support
- **Be respectful**: Don't make excessive requests
- **Use filters**: Be specific to reduce response sizes
- **Implement caching**: Cache responses when appropriate
- **Handle errors gracefully**: Implement proper error handling
## Development
```bash
# Install dependencies
npm install
# Build the project
npm run build
# Run linting
npm run lint
# Fix linting issues
npm run lint:fix
# Clean build directory
npm run clean
```
## API Reference
For detailed API documentation, visit [OpenAlex API Documentation](https://docs.openalex.org/).
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Ensure all tests pass
6. Submit a pull request
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Support
- 📖 [OpenAlex Documentation](https://docs.openalex.org/)
- 💬 [OpenAlex Community](https://github.com/ourresearch/openalex-guts/discussions)
- 🐛 [Report Issues](https://github.com/pepearce/openalex-client/issues)
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for version history and updates.