John Hubler
John Hubler

Reputation: 909

API post request working in PostMan, but not in Laravel Application

I am attempting to submit a list of domain aliases to an API endpoint, and as the title says, it works perfectly in PostMan.. but when I try to add it to my Laravel application, I am getting a "502 Bad Gateway" error.

The API in question is for Cloudways. Documentation can be found here: https://developers.cloudways.com/docs/#!/AppManagementApi#updateAppAliases

The specific endpoint in question is https://api.cloudways.com/api/v1/app/manage/aliases

In PostMan, I first hit https://api.cloudways.com/api/v1/oauth/access_token in order to get an access token. This runs fine, and it spits out a bearer token, as expected.

From there, I send that data along as a bearer token, along with the requested parameters.

I am sending the data as raw JSON, and it looks like so:

{
    "server_id": 111111,
    "app_id": 2222222,
    "aliases": ["testing.somedomain.com", "another.somedomain.com"]
}

When I submit this in PostMan, I get a 200 status, and I can check the application and see the domain aliases added, as expected.

From there, I take the code that PostMan produces, and paste it into a method in my Controller.

This is the code:

public function updateDomainAliases() {
    $domainList = array();
    foreach($allDomains as $key => $singleDomain) {
        $domain = $singleDomain->subdomain.".".$singleDomain->domain;
        $domainList[] = $domain;
    }

    $accessToken = $this->getAccessToken(env('CLOUDWAYS_EMAIL'), env('CLOUDWAYS_API_KEY'));
    $domainResponse = $this->addDomainAliases($accessToken, env('CLOUDWAYS_SERVER_ID'), env('CLOUDWAYS_APP_ID'), $domainList);
}

private function getAccessToken($email, $apiKey) {
    $response = Http::post('https://api.cloudways.com/api/v1/oauth/access_token', [
        'email' => $email,
        'api_key' => $apiKey,
    ]);

    return $response->json()['access_token'];
}

private function addDomainAliases($accessToken, $serverID, $appID, $aliases) {
    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => 'https://api.cloudways.com/api/v1/app/manage/aliases',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS =>'{
            "server_id": 111111,
            "app_id": 2222222,
            "aliases": ["testing.somedomain.com", "another.subdomain.com"]
        }',
        CURLOPT_HTTPHEADER => array(
            'Content-Type: application/json',
            'Authorization: Bearer '.$accessToken
        ),
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    echo $response;
}

So... as you can see, my first step is generating an Access Token, which a simple dd() command verifies is working properly.

I then send that access token to my addDomainAliases() function, along with the server ID, app ID, and aliases, and then run a cURL command to send the data to the API.

A couple of things worth noting here:

So – I turn to you fine people. What am I missing here?


Edit:

Here are my Postman Requests:

Getting the Access Token: Access Token: Params

Access Token: Headers

Sending Domain Alias Data: Alias: Authorization Alias: Headers Alias: Body


Edits: Part 2

I adjusted my addDomainAliases function as follows:

private function addDomainAliases($accessToken, $dump = null) {
    $url = 'https://api.cloudways.com/api/v1/app/manage/aliases';

    $headers = [
        'Content-Type' => 'application/json',
        'Authorization' => 'Bearer ' .$accessToken
    ];

    $payload = [
        'server_id' => 111111,
        'app_id' => 2222222,
        'aliases' => ['testing.somedomain.com', 'another.somedomain.com']
    ];

    $request = Http::withOptions([
        'verify' => config('app.env') == 'production',
    ])->withHeaders($headers);

    if($dump) {
        $request->dd()->post($url, $payload);
    } else {
        $response = $request->post($url, $payload);
    }

    dd($response);

I then called the function first as so:

$addDomains = $this->addDomainAliases($accessToken, true);

Which gave me the following response: dd() response

I then called the same function, setting the second parameter to false.

In doing so, I once again got the 502 Bad Gateway error.

Upvotes: 0

Views: 476

Answers (1)

silver
silver

Reputation: 5311

1st, check the laravel error log in /storage/logs and see whats in there when you try to do a request.

2nd, dont use env function, use config instead, the env function should only be use in configuration files, once the configuration is cache, that function will return null, any call outside config files should use config function. you can add another file inside /config for your API keys that calls the env function, or just add it in /config/app.php file

3rd, use the HTTP Client instead of using curl, this way, you can easily debug and verify your actual request.

below is a sample of your addDomainAliases method that uses HTTP client. if you pass true in 2nd param, you will see the actual request headers, body and all request related data

private function addDomainAliases($accessToken, $dump = null ) {

    $url = 'https://api.cloudways.com/api/v1/app/manage/aliases';

    $headers = [
        'Content-Type' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken
    ];
    
    $payload = [
        'server_id' => '111111'
        'app_id' => '2222222'
        'aliases' => ['testing.somedomain.com', 'another.subdomain.com']
    ];

    $request = Http::withOptions([
        'verify' => config('app.env') == 'production',
    ])->withHeaders($headers);

    // dump the actual request and verify the url, headers and payload are all correct
    if ( $dump ) 
        $request->dd()->post($url, $payload );

    $response = $request->post( $url, $payload );

    .
    .
    .
        
}

Additionally, also very that your getAccessToken request also returns the data you expect, if not also dump its request and verify all data are correct

Upvotes: 1

Related Questions