bluetea/jira-rest-api
Object-oriented PHP client for Atlassian JIRA REST API. Configure a Curl or Guzzle client with basic authentication, then use endpoint classes (e.g., ProjectEndpoint) to call JIRA /rest/api/2 methods and retrieve projects and more.
Installation:
composer require bluetea/jira-rest-api
Ensure your Laravel project has guzzlehttp/guzzle or php-curl installed (required for HTTP clients).
First Connection:
use Bluetea\Api\Authentication\BasicAuthentication;
use Bluetea\Api\Client\GuzzleClient;
$client = new GuzzleClient(
'https://your-jira-instance/rest/api/2',
new BasicAuthentication('email@example.com', 'api-token')
);
api-token with a Jira API token..env and inject via a service container.First Endpoint Call:
use Bluetea\Jira\Endpoint\IssueEndpoint;
$issueEndpoint = new IssueEndpoint($client);
$issues = $issueEndpoint->findAll(['jql' => 'project = TEST']);
return response()->json($issues);
Jira/Endpoint namespace for available endpoints (e.g., ProjectEndpoint, UserEndpoint).src/Jira/Endpoint/ for pre-built endpoints (e.g., IssueEndpoint, CommentEndpoint).Service Layer Integration: Create a Laravel service to encapsulate Jira logic:
namespace App\Services;
use Bluetea\Api\Client\GuzzleClient;
use Bluetea\Jira\Endpoint\IssueEndpoint;
class JiraService {
protected $issueEndpoint;
public function __construct(GuzzleClient $client) {
$this->issueEndpoint = new IssueEndpoint($client);
}
public function createIssue(array $issueData) {
return $this->issueEndpoint->create($issueData);
}
}
AppServiceProvider:
$this->app->bind(JiraService::class, function ($app) {
$client = new GuzzleClient(
config('services.jira.url'),
new BasicAuthentication(
config('services.jira.email'),
config('services.jira.token')
)
);
return new JiraService($client);
});
Query Builder Pattern: Chain methods for complex queries:
$issues = $issueEndpoint
->findAll(['jql' => 'project = TEST'])
->filter(fn($issue) => $issue['status']['name'] === 'In Progress')
->map(fn($issue) => $issue['key']);
Event-Driven Actions:
Trigger Jira actions on Laravel events (e.g., create a Jira issue on OrderCreated):
use App\Services\JiraService;
Event::listen(OrderCreated::class, function ($order) {
$jiraService = app(JiraService::class);
$jiraService->createIssue([
'project' => ['key' => 'PROJ'],
'summary' => "New order #{$order->id}",
'description' => $order->details,
]);
});
Rate Limiting: Jira enforces rate limits. Cache responses aggressively:
$cacheKey = 'jira_issues_' . md5($jql);
return Cache::remember($cacheKey, now()->addMinutes(5), function () use ($issueEndpoint, $jql) {
return $issueEndpoint->findAll(['jql' => $jql]);
});
Error Handling:
Wrap calls in a try-catch to handle Jira-specific errors (e.g., 404 Not Found for invalid issues):
try {
$issue = $issueEndpoint->get('TEST-123');
} catch (\Bluetea\Api\Exception\ApiException $e) {
Log::error("Jira API Error: {$e->getMessage()}");
return response()->json(['error' => 'Issue not found'], 404);
}
Webhooks:
Use Jira’s webhooks to push events to Laravel (e.g., via GuzzleHttp\Client in a route):
Route::post('/jira-webhook', function (Request $request) {
$payload = $request->json()->all();
// Process webhook (e.g., update Laravel DB)
});
Authentication:
GuzzleClient directly with custom middleware.Endpoint Versioning:
/rest/api/2. For Cloud, use /rest/api/3 (update the base URL in GuzzleClient).Pagination:
findAll() return paginated results. Use ->nextPage() or handle manually:
$issues = [];
$startAt = 0;
do {
$page = $issueEndpoint->findAll(['jql' => 'project = TEST', 'startAt' => $startAt]);
$issues = array_merge($issues, $page);
$startAt += count($page);
} while (count($page) > 0);
Field Validation:
$validFields = ['project', 'summary', 'description', 'issuetype'];
$issueData = array_intersect_key($input, array_flip($validFields));
Enable Guzzle Debugging:
Add a GuzzleHandler to log requests:
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
$client = new GuzzleClient(
config('services.jira.url'),
new BasicAuthentication(config('services.jira.email'), config('services.jira.token')),
HandlerStack::create([
Middleware::tap(function ($request) {
Log::debug('Jira Request:', [
'url' => (string) $request->getUri(),
'method' => $request->getMethod(),
'body' => $request->getBody() ? $request->getBody()->getContents() : null,
]);
}),
])
);
Common HTTP Errors:
/rest/api/2/issue vs. /rest/api/3/issue).Custom Endpoints: Extend the library by creating new endpoints. Example:
namespace App\Jira\Endpoint;
use Bluetea\Api\Client\AbstractClient;
use Bluetea\Api\Endpoint\AbstractEndpoint;
class CustomEndpoint extends AbstractEndpoint {
protected $basePath = 'custom';
public function customAction($param) {
return $this->client->get("{$this->basePath}/{$param}");
}
}
Middleware:
Add request/response middleware to GuzzleClient:
$client = new GuzzleClient(
config('services.jira.url'),
new BasicAuthentication(...),
[],
[
'headers' => ['X-Atlassian-Token' => 'no-check'],
'timeout' => 30,
]
);
Testing: Mock the client in PHPUnit:
$mockClient = $this->createMock(GuzzleClient::class);
$mockClient->method('get')->willReturn(['issues' => []]);
$issueEndpoint = new IssueEndpoint($mockClient);
$result = $issueEndpoint->findAll([]);
How can I help you explore Laravel packages today?