Weave Code
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

Connect Rest Api Bundle Laravel Package

backend2-plus/connect-rest-api-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require backend2-plus/connect-rest-api-bundle

The bundle auto-registers in Symfony 7+/8.0.

  1. Configure .env:

    CONNECT_REST_API_USERNAME=your_api_username
    CONNECT_REST_API_PASSWORD=your_api_password
    
  2. Basic Usage: Inject ConnectRestApiService into any controller/service:

    use Backend2Plus\ConnectRestApiBundle\Service\ConnectRestApiService;
    
    public function __construct(private ConnectRestApiService $apiClient) {}
    
    // Example GET request
    $response = $this->apiClient->get('https://api.example.com/data');
    $data = json_decode($response->getContent(), true);
    

First Use Case: Fetching API Data

// In a controller/service
$users = $this->apiClient->get('https://api.example.com/users')->toArray();
return $this->json($users);

Implementation Patterns

1. Service Layer Integration

Pattern: Use the service in dedicated API service classes to abstract API calls.

// src/Service/ExternalApiService.php
class ExternalApiService {
    public function __construct(private ConnectRestApiService $apiClient) {}

    public function fetchUser(int $id): array {
        return $this->apiClient->get("https://api.example.com/users/{$id}")->toArray();
    }
}

2. Request/Response DTOs

Pattern: Create DTOs for API responses to enforce structure.

// src/DTO/UserDto.php
class UserDto {
    public function __construct(
        public string $id,
        public string $name,
        public string $email
    ) {}
}

// Usage
$response = $this->apiClient->get('https://api.example.com/users/1');
$userDto = new UserDto(
    $response['id'],
    $response['name'],
    $response['email']
);

3. Configuration Management

Pattern: Override bundle config per environment (e.g., config/packages/dev/connect_rest_api.yaml):

connect_rest_api:
    username: '%env(resolve:DEV_API_USERNAME)%'
    password: '%env(resolve:DEV_API_PASSWORD)%'
    base_uri: 'https://dev-api.example.com'

4. Error Handling Middleware

Pattern: Centralize error handling in a middleware or interceptor.

// src/EventListener/ApiErrorListener.php
class ApiErrorListener {
    public function onKernelException(GetResponseForExceptionEvent $event) {
        $exception = $event->getThrowable();
        if ($exception instanceof \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface) {
            $event->setResponse(new Response('API Error', 400));
        }
    }
}

5. Testing

Pattern: Mock ConnectRestApiService in tests using Symfony’s HTTP Client mocks.

// tests/Service/ExternalApiServiceTest.php
public function testFetchUser() {
    $mockResponse = new Response(json_encode(['id' => 1, 'name' => 'Test']));
    $httpClient = $this->createMock(HttpClientInterface::class);
    $httpClient->method('request')->willReturn($mockResponse);

    $service = new ExternalApiService($httpClient);
    $result = $service->fetchUser(1);
    $this->assertEquals('Test', $result['name']);
}

Gotchas and Tips

1. Authentication Pitfalls

  • Gotcha: Hardcoding credentials in config/packages/connect_rest_api.yaml bypasses .env overrides. Fix: Always use %env() placeholders:

    connect_rest_api:
        username: '%env(CONNECT_REST_API_USERNAME)%'
    
  • Tip: For multi-environment setups, use env() in PHP:

    $this->apiClient->connector('GET', $url, [], [
        'auth_basic' => [$this->getEnv('API_USERNAME'), $this->getEnv('API_PASSWORD')]
    ]);
    

2. HTTP Client Quirks

  • Gotcha: The bundle uses Symfony’s HttpClient, which may throw ClientExceptionInterface for 4xx/5xx responses. Fix: Catch specifically:

    try {
        $response = $this->apiClient->get($url);
    } catch (ClientExceptionInterface $e) {
        if ($e->getStatusCode() === 404) {
            // Handle 404
        }
    }
    
  • Tip: Disable SSL verification for testing (not production!):

    $response = $this->apiClient->connector('GET', $url, [], [
        'verify_peer' => false,
    ]);
    

3. Performance Considerations

  • Gotcha: Reusing the same HttpClient instance (default behavior) can cause connection pooling issues. Fix: Configure the client per request if needed:

    $response = $this->apiClient->connector('GET', $url, [], [
        'http_client' => HttpClient::create(['timeout' => 30]),
    ]);
    
  • Tip: Cache responses for read-heavy APIs:

    $cacheKey = 'api_users_' . md5($url);
    if (!$cached = $this->cache->get($cacheKey)) {
        $cached = $this->apiClient->get($url)->toArray();
        $this->cache->set($cacheKey, $cached, 3600);
    }
    

4. Extension Points

  • Tip: Extend the service to add retry logic:
    // src/Service/ResilientApiService.php
    class ResilientApiService extends ConnectRestApiService {
        public function resilientGet(string $url, int $retries = 3): Response {
            $attempt = 0;
            while ($attempt < $retries) {
                try {
                    return parent::get($url);
                } catch (TransportExceptionInterface $e) {
                    $attempt++;
                    if ($attempt === $retries) throw $e;
                    sleep(2 ** $attempt); // Exponential backoff
                }
            }
        }
    }
    

5. Debugging

  • Tip: Enable HTTP Client debug mode in config/packages/dev/connect_rest_api.yaml:

    connect_rest_api:
        debug: true
    

    Logs requests/responses to var/log/dev.log.

  • Gotcha: Headers like Content-Type: application/json are auto-set for non-GET requests. Override with:

    $this->apiClient->connector('POST', $url, $data, [
        'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
    ]);
    

6. Security

  • Tip: Rotate credentials via environment variables and use Symfony’s ParameterBag for runtime overrides:
    $this->apiClient->setCredentials(
        $this->container->getParameter('api.username'),
        $this->container->getParameter('api.password')
    );
    

7. Common Errors

Error Cause Solution
InvalidArgumentException Invalid HTTP method (e.g., PATCH) Use uppercase methods ('PATCH', not 'patch').
TransportExceptionInterface Network timeout Increase timeout in options.
ClientExceptionInterface 4xx/5xx HTTP status Check $response->getStatusCode().
JsonException Malformed JSON response Validate API response structure.

---
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor