Laravel Integration

Scholarly Providers ships with a first-class Laravel bridge that registers adapters, configures caching, and exposes a facade for quick access.

Installation

composer require scholarly/providers

The service provider uses package discovery. If discovery is disabled, add the provider manually in config/app.php:

'providers' => [
    // ...
    Scholarly\Laravel\ScholarlyServiceProvider::class,
],

Configuration

Publish the configuration file to customise adapters, HTTP timeouts, and caching:

php artisan vendor:publish --tag=scholarly-config

The published file (config/scholarly.php) reads from the following environment variables:

Usage

Resolve the factory or use the facade to obtain adapters:

use Scholarly\Laravel\Facades\Scholarly;
use Scholarly\Contracts\Query;

$adapter = Scholarly::adapter('openalex');
$results = $adapter->searchWorks(Query::from(['q' => 'graph neural networks']));

Inject the factory or default adapter into your services:

use Scholarly\Factory\AdapterFactory;

class WorkService
{
    public function __construct(private AdapterFactory $factory) {}

    public function openAlexWorks(): array
    {
        return $this->factory->adapter('openalex')->searchWorks(Query::from(['q' => 'vision']));
    }
}

The graph exporter is bound for convenience:

$graph = Scholarly::graphExporter()->buildWorkCitationGraph(['openalex:W123'], Query::from(['limit' => 50]));

### Overriding PSR dependencies
Bind your own PSR-18 client, PSR-17 factories, cache store, or logger to integrate platform choices like Symfony HttpClient or Redis caching.

```php
use Psr\Http\Client\ClientInterface as Psr18;
use Psr\SimpleCache\CacheInterface as Psr16;
use Illuminate\Support\Facades\Cache;

$this->app->bind(Psr18::class, fn () => new MyHttpClient());
$this->app->bind(Psr16::class, fn () => Cache::store('redis'));

Custom Clients & Caching

Bind PSR-18, PSR-17, cache, or logger implementations in your container to override defaults.

$this->app->bind(ClientInterface::class, fn () => new Psr18Client());
$this->app->bind(CacheInterface::class, fn () => Cache::store('redis')->getRepository());

Set SCHOLARLY_LOG_CHANNEL to reuse an application log channel.

Advanced Configuration

Custom HTTP Client

// In a service provider
use Psr\Http\Client\ClientInterface;
use Symfony\Component\HttpClient\Psr18Client;

public function register()
{
    $this->app->bind(ClientInterface::class, function() {
        return new Psr18Client(HttpClient::create([
            'timeout' => 60,
            'headers' => ['User-Agent' => 'MyApp/1.0'],
        ]));
    });
}

Redis Caching Setup

// config/scholarly.php
return [
    'cache_store' => 'redis',
    'cache_ttl' => [
        'metadata' => 3600, // 1 hour for works/authors
        'search' => 900, // 15 minutes for search results
        'graph' => 7200, // 2 hours for graph data
    ],
];

Queue Integration

use Scholarly\Laravel\Facades\Scholarly;

// In a queued job
class BuildCitationGraphJob implements ShouldQueue
{
    public function handle()
    {
        $exporter = Scholarly::graphExporter();
        $graph = $exporter->buildWorkCitationGraph(
            $this->workIds,
            Query::from(['limit' => 200])
        );
        // Process the graph...
    }
}

Testing with Package

// tests/Feature/ScholarlyTest.php
use Scholarly\Laravel\Facades\Scholarly;

class ScholarlyTest extends TestCase
{
    public function test_can_search_works()
    {
        $results = Scholarly::adapter('openalex')
            ->searchWorks(Query::from(['q' => 'test']));
        $this->assertInstanceOf(Paginator::class, $results);
    }
}

Production Deployment

Performance Considerations

Monitoring & Logging

// Custom logger for scholarly operations
Log::channel('scholarly')->info('Graph export completed', [
    'nodes' => $graph->nodeCount(),
    'edges' => $graph->edgeCount(),
    'duration' => $exportTime
]);

Core Concepts: Contracts Architecture Getting Started
Features: Graph Analytics Laravel Integration Provider Adapters
Development: Extending GitHub Repository  
External Resources: OpenAlex API Semantic Scholar API Crossref API