Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Jasper Rest Client Laravel Package

sigedi/jasper-rest-client

Lightweight PHP/Laravel client for the JasperReports Server REST API. Run reports, pass parameters, select export formats such as PDF, XLSX, and CSV, and handle authentication through a simple, framework-friendly interface. A convenient way to embed JasperReports output in your Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a bare PHP client for the JasperReports Server REST API (a fork of jaspersoft/jrs-rest-php-client), not a Laravel package. There is no service provider, facade, config file, or auto-discovery — expect to wire it into Laravel yourself in about 15 minutes.

Install

composer require sigedi/jasper-rest-client:^2.0

Pin the constraint. 2.0.0 is a major bump from 1.0.0, so treat the upgrade as potentially breaking: diff 1.0.0...2.0.0 on GitHub (and src/ against jaspersoft/jrs-rest-php-client) before swapping it under existing code. The release is small and reviewable — one PR, one contributor — so this is a 15-minute read, not a leap of faith.

What 2.0.0 actually changes (from the release notes):

  • Symfony 7 support — this is the headline for Laravel users. Laravel 11 ships Symfony 7 components, so ^2.0 no longer risks a dependency conflict with a modern Laravel app. If you previously pinned Symfony 6 or ran an older Laravel, this is your reason to upgrade.
  • Encoding fix — directly relevant to the URL-encoding pitfall below. Verify it covers your case rather than assuming.
  • "Increase code quality" — vague, and the usual source of breaking changes: typed properties/return types, stricter signatures, possibly normalized exception types. Read the diff.

Where to look first

  • Vendor source: vendor/sigedi/jasper-rest-client/src/ — the entry point is Jaspersoft\Client\Client.
  • Read the Client constructor signature. Auth mode and org ID handling vary between forks, and a major bump is exactly when that signature moves.
  • Check composer.json for the PHP floor. Symfony 7 implies PHP 8.2+; if you're on 8.1 or below, stay on 1.x.

Minimal wiring

  1. Add credentials to config/services.php:
'jasper' => [
    'host'     => env('JASPER_HOST'),      // e.g. https://jasperserver.example.com:8443/jasperserver
    'username' => env('JASPER_USER'),
    'password' => env('JASPER_PASSWORD'),
    'org_id'   => env('JASPER_ORG_ID'),    // null for root org
],
  1. Bind a singleton in AppServiceProvider:
use Jaspersoft\Client\Client;

$this->app->singleton(Client::class, function ($app) {
    $c = $app['config']['services.jasper'];
    return new Client($c['host'], $c['username'], $c['password'], $c['org_id']);
});

Check the argument order against the 2.0.0 constructor before copying this verbatim.

  1. First use — stream a PDF report:
public function show(Client $jasper)
{
    $pdf = $jasper->reportService()->runReport('/reports/sales/summary', 'pdf', null, null, [
        'year' => 2024,
    ]);

    return response($pdf, 200, ['Content-Type' => 'application/pdf']);
}

That single flow (reportService()->runReport() → binary → response) covers 80% of real-world use.

Implementation Patterns

Wrap the client in your own service. Don't inject Jaspersoft\Client\Client into controllers — wrap it so you can mock, normalize params, centralize error handling, and absorb breaking changes from a major bump in one place.

class JasperReportService
{
    public function __construct(private Client $client) {}

    public function pdf(string $uri, array $params = []): string
    {
        return $this->client->reportService()->runReport($uri, 'pdf', null, null, $params);
    }
}

Stream large reports instead of buffering. runReport() returns the whole body as a string; for 50MB+ XLSX exports use response()->streamDownload(), or better — use the job service for anything that takes more than a few seconds:

$job = $this->client->jobService()->createJob('/reports/heavy','xlsx');
// poll jobService()->getJobState($job->id) from a queued job
$output = $this->client->jobService()->fetchNextOutput($job->id);

Drive async jobs from a Laravel ShouldQueue job, not a controller.

Multi-tenant orgs. The client is bound to one org at construction time. If you're multi-tenant, don't use a singleton — instantiate per-request with the tenant's org ID (or maintain a keyed singleton per org).

Caching the resource tree. resourceService()->getResourceList() hits the server on every call. Cache the report catalog with Cache::remember('jasper:catalog', 3600, fn () => $this->client->resourceService()->getResourceList('/')). Bust the cache when you deploy or via a scheduled command.

Testing. The Client wraps GuzzleHttp\Client internally in most forks. In tests, mock Client itself (cleanest) rather than fighting the internal HTTP layer. Assert your JasperReportService calls the right runReport URI and params. After a major bump, re-run these tests against real Jasper — typed return values and stricter signatures are the kind of change mocks happily hide.

Facade optional. If you want Jasper::reportService()... syntax, register a facade pointing at the singleton — but for a single integration point a typed service is clearer.

Parameter conventions. Pass params as a flat associative array. Multi-select values go as arrays — the client serializes them, but check whether the fork uses PLURAL-style naming or plain arrays. Dates should be ISO 8601 strings; the server expects YYYY-MM-DD or full timestamps. If you use multi-selects or params with spaces/#, smoke-test them specifically on 2.0.0 — the encoding fix is the one behavioral change in this release.

Gotchas and Tips

  • 2.0.0 is a major bump — budget for a breaking change. "Increase code quality" is not a changelog. Assume tighter type declarations and possibly altered exception classes until the diff says otherwise. Upgrade on a branch, run your JasperReportService test suite, and exercise one real report of each output type before merging.
  • No Laravel integration. There is no extra.laravel in composer.json — no auto-discovery, no config publish, no facade. Everything above is manual, and that's fine.
  • Symfony 7 means PHP 8.2+ and a modern Laravel. This is the good news in 2.0.0, and also a hard floor: older apps stay on 1.x, and you now have two supported lines to reason about if you run multiple projects.
  • LGPL-3.0 license. This is copyleft. Linking to it in a SaaS app is generally OK, but if you redistribute your app (desktop, on-prem, marketplace), you may have obligations on this library. Get legal sign-off before shipping in a distributed product.
  • Report URIs must be URL-encoded. 2.0.0 claims to fix an encoding issue, but "fixes encoding issue" is one line for an unknown set of cases. If you build URIs dynamically from user input, keep using rawurlencode() per path segment — spaces and # silently break requests, and a partial fix is worse than a known bug because it stops being reproducible.
  • Auth mode is a constructor flag in some forks. Basic auth is the default; SSO ticket auth (.ticket cookie) requires a different constructor or header injection. A major version is exactly when this moves — re-read the constructor signature in vendor code, not the docs.
  • Timeouts are your problem. Long reports return after the default Guzzle timeout (~30s) and throw ConnectException. For heavy reports, use jobService() — do not just bump the timeout; you'll tie up PHP-FPM workers.
  • Binary content types. runReport() returns raw bytes. When returning to a browser, always set Content-Type (application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) and Content-Disposition — the client does not set these.
  • Error handling is exception-based but thin. Bad params return a 4xx from Jasper and the client throws a generic \Exception (or Guzzle exception, depending on fork). 2.0.0's quality pass may have changed which type surfaces; re-verify your catch blocks. Wrap and translate to Laravel-friendly errors — the raw exception message often contains Jasper's XML error body, which is not user-safe.
  • Adoption signal is still thin, but better. Still a low-star, low-dependent fork — you are likely the first person to hit any given bug. The upside versus the 1.0.0 assessment: the 2.0.0 changes arrived via a reviewable PR from an outside contributor, so you can audit intent instead of reverse-engineering an undocumented "small enhancement."
  • Maintenance risk. Two releases, two contributors, one fork. Treat it as vendored code: fork it into your repo if you need to carry patches, so Composer never surprises you with a re-tag. A 2.0.0 on a project this small is as likely to be a modernization spike as the start of a cadence — don't plan around future releases.
  • Extension point: almost everything goes through Jaspersoft\Client\Client → service objects (reportService(), jobService(), resourceService(), userService(), permissionService(), administrationService()). If you need custom behavior (retry, logging, header injection), decorate the Client rather than patch vendor — subclass and override, or wrap with your JasperReportService.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel