Notdavis's avatar

Code that relies on external API - ServiceProvider or Model?

Our Laravel App has to connect to external SOAP API, with requirements to validate data, upload, and download files.

Data will hit our Laravel API route, we will have to verify/auth, validate the data, reformat and create files from the data, then submit it to the external API along with authentication details, handle response, log some of the return data, then return other portions of the data to the original requester who hit our Laravel API.

In the before-fore times, half a decade ago, I made a horrible library to handle this. I don't want to do that again.

I am unsure whether all this code should become a service provider or a model within Lavavel, and would love feedback on thoughts of how/where to put this code.

0 likes
2 replies
LaryAI's avatar
Level 58

Based on the description provided, it sounds like the code that interacts with the external SOAP API should be placed in a service class. This service class can then be injected into the appropriate controllers or other classes that need to interact with the API.

Here's an example of what the service class might look like:

<?php

namespace App\Services;

use App\Exceptions\ApiException;
use App\Models\User;
use Illuminate\Support\Facades\Http;

class ExternalApiService
{
    private $baseUrl;
    private $apiKey;

    public function __construct()
    {
        $this->baseUrl = config('external_api.base_url');
        $this->apiKey = config('external_api.api_key');
    }

    public function validateData(array $data): bool
    {
        // Perform validation logic here
    }

    public function uploadFile(string $filePath): string
    {
        // Perform file upload logic here
    }

    public function downloadFile(string $fileId): string
    {
        // Perform file download logic here
    }

    public function submitData(array $data): array
    {
        $response = Http::post($this->baseUrl . '/submit', [
            'api_key' => $this->apiKey,
            'data' => $data,
        ]);

        if ($response->failed()) {
            throw new ApiException('Failed to submit data to external API');
        }

        $responseData = $response->json();

        // Perform logging logic here

        return $responseData;
    }
}

In this example, the service class has methods for validating data, uploading and downloading files, and submitting data to the external API. It also handles authentication by using an API key that is stored in the Laravel config.

To use this service class in a controller, you would first need to create an instance of it:

$externalApiService = new ExternalApiService();

Then you could call its methods as needed:

if (!$externalApiService->validateData($requestData)) {
    return response()->json(['error' => 'Invalid data'], 400);
}

$filePath = $externalApiService->uploadFile($file);

$dataToSubmit = formatData($requestData, $filePath);

$responseData = $externalApiService->submitData($dataToSubmit);

return response()->json($responseData);

By using a service class like this, you can keep your code organized and modular, and make it easier to test and maintain.

1 like
Notdavis's avatar

And in the case where things get more complicated examples, because the whole create files, decode files, to act as the in between for data -> weirdly formatted files specific to this API.

To avoid bloat of the API service provider, should that also become another CreateWeirdFileService or does that fit better somewhere else in Laravel ?

Please or to participate in this conversation.