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

Microsoft Graph Core Laravel Package

microsoft/microsoft-graph-core

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require microsoft/microsoft-graph-core
    
  2. Register your app in Azure Portal and note:

    • tenantId
    • clientId
    • clientSecret
  3. First API call (e.g., fetch current user):

    use Microsoft\Graph\Core\GraphClientFactory;
    use Microsoft\Graph\Core\Authentication\ClientCredentialContext;
    use Microsoft\Graph\Core\Authentication\GraphPhpLeagueAccessTokenProvider;
    
    // Auth setup
    $tokenRequestContext = new ClientCredentialContext(
        'your-tenant-id',
        'your-client-id',
        'your-client-secret'
    );
    $tokenProvider = new GraphPhpLeagueAccessTokenProvider($tokenRequestContext);
    $accessToken = $tokenProvider->getAuthorizationTokenAsync('https://graph.microsoft.com')->wait();
    
    // HTTP client
    $httpClient = GraphClientFactory::createWithConfig([
        'headers' => ['Authorization' => 'Bearer ' . $accessToken]
    ]);
    
    // Execute request
    $response = $httpClient->get('/v1.0/me');
    $user = json_decode($response->getBody());
    

Key First Use Cases

  • User data: Fetch /me, /users/{id}
  • Mail operations: /me/messages, /users/{id}/mailFolders
  • Batch requests: Send multiple requests in a single call (see BatchRequestContent)

Implementation Patterns

Authentication Workflows

  1. Client Credentials Flow (for app-only access):

    $tokenProvider = new GraphPhpLeagueAccessTokenProvider(
        new ClientCredentialContext($tenantId, $clientId, $clientSecret)
    );
    
  2. Custom Auth Provider (for OAuth2 flows like user/delegated):

    use Microsoft\Graph\Core\Authentication\GraphPhpLeagueAuthenticationProvider;
    $authProvider = new GraphPhpLeagueAuthenticationProvider(
        new \League\OAuth2\Client\Provider\GenericProvider([...])
    );
    $httpClient = GraphClientFactory::createWithAuthProvider($authProvider);
    
  3. Token Caching (for performance):

    $tokenProvider = new GraphPhpLeagueAccessTokenProvider(
        $tokenRequestContext,
        new \League\OAuth2\Client\Token\AccessToken(['access_token' => 'cached-token'])
    );
    

Request Patterns

  1. Simple GET Request:

    $response = $httpClient->get('/v1.0/users');
    $users = json_decode($response->getBody());
    
  2. POST with Payload:

    $response = $httpClient->post('/v1.0/me/sendMail', [
        'json' => [
            'message' => [...]
        ]
    ]);
    
  3. Batch Requests (for efficiency):

    use Microsoft\Graph\Core\Http\BatchRequestContent;
    $batch = new BatchRequestContent();
    $batch->addRequest('GET', '/v1.0/me/messages', null);
    $batch->addRequest('GET', '/v1.0/me/calendar/events', null);
    
    $response = $httpClient->post('/v1.0/$batch', [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => $batch->getBody()
    ]);
    

Integration Tips

  • Middleware: Extend GraphClientFactory to add custom middleware (e.g., logging, retries):

    $stack = \GuzzleHttp\HandlerStack::create();
    $stack->push(\GuzzleHttp\Middleware::tap(function ($request) {
        // Log request
    }));
    $httpClient = GraphClientFactory::createWithConfig([
        'handler' => $stack
    ]);
    
  • Pagination: Handle @odata.nextLink in responses for large datasets:

    $nextLink = $response->getHeader('odata-nextlink')[0] ?? null;
    while ($nextLink) {
        $response = $httpClient->get($nextLink);
        $nextLink = $response->getHeader('odata-nextlink')[0] ?? null;
    }
    
  • Error Handling: Use try-catch with Microsoft\Graph\Core\Http\GraphServiceException:

    try {
        $response = $httpClient->get('/v1.0/nonexistent');
    } catch (\Microsoft\Graph\Core\Http\GraphServiceException $e) {
        logger()->error('Graph API Error: ' . $e->getMessage());
    }
    

Gotchas and Tips

Pitfalls

  1. Token Expiry:

    • Tokens expire (~1 hour). Cache tokens and implement refresh logic:
      if ($tokenProvider->hasExpired()) {
          $token = $tokenProvider->getNewToken()->wait();
      }
      
  2. National Clouds:

    • Hardcoding graph.microsoft.com may fail in non-US regions. Use GraphConstants::REST_ENDPOINT or specify custom endpoints:
      $tokenProvider->getAuthorizationTokenAsync('https://graph.microsoft.us');
      
  3. Batch Request Limits:

    • Microsoft Graph limits batch requests to 20 operations. Exceeding this throws an error:
      if ($batch->getRequests()->count() > 20) {
          throw new \RuntimeException('Batch request exceeds 20 operations');
      }
      
  4. PHP Version:

    • PHP 8.2+ required (as of v3.0.0). Older versions (7.4–8.1) are unsupported.
  5. CORS/Proxy Issues:

    • If using behind a proxy, configure Guzzle’s proxy option in GraphClientFactory:
      $httpClient = GraphClientFactory::createWithConfig([
          'proxy' => 'http://your-proxy:port'
      ]);
      

Debugging Tips

  1. Enable Guzzle Debugging:

    $httpClient = GraphClientFactory::createWithConfig([
        'debug' => fopen('graph_debug.log', 'w'),
        'headers' => ['Authorization' => 'Bearer ' . $accessToken]
    ]);
    
  2. Validate Tokens:

  3. Check Response Headers:

    • Inspect odata-nextlink, odata-count, and Retry-After headers for pagination/rate-limiting clues.

Extension Points

  1. Custom Models:

    • Extend Microsoft\Graph\Core\GraphEntity to add domain-specific properties:
      class CustomUser extends \Microsoft\Graph\Core\GraphEntity {
          public string $customField;
      }
      
  2. Middleware Stack:

    • Add retry logic or logging middleware:
      $stack->push(\GuzzleHttp\Middleware::retry(
          function ($retries, $request, $exception) {
              return $retries < 3 && $exception instanceof \GuzzleHttp\Exception\ConnectException;
          },
          function ($retries, \GuzzleHttp\RequestOptions $options) {
              return 100 * $retries; // Exponential backoff
          }
      ));
      
  3. Authentication Providers:

    • Implement Microsoft\Graph\Core\Authentication\IGraphAuthenticationProvider for custom auth flows (e.g., Azure AD B2C):
      class CustomAuthProvider implements IGraphAuthenticationProvider {
          public function authenticateRequest(\GuzzleHttp\Psr7\Request $request): \GuzzleHttp\Psr7\Request {
              $request = $request->withHeader('Authorization', 'Bearer ' . $this->getToken());
              return $request;
          }
      }
      

Configuration Quirks

  • Default Headers: The SDK adds Accept: application/json and Content-Type: application/json by default. Override in GraphClientFactory if needed.
  • Timeouts: Default timeouts are 5 seconds for connect and 10 seconds for request. Adjust via Guzzle config:
    $httpClient = GraphClientFactory::createWithConfig([
        'timeout' => 30.0,
        'connect_timeout' => 10.0
    ]);
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours