Search code examples
phpdockerlumenguzzle6

Guzzle not using base uri when a dynamic endpoint is selected (Works locally but not on K8S)


I am building an API Gateway and a bunch of microservices to run my company. I have elected to use PHP as it is what I have the most experience with.

Local Setup: Opensuse Tumbleweed, PHPStorm, php7.3, SQLite, docker Remote Setup: GKE, PHP7.3 Percona Xtra DB and Docker

I am using Laravels Lumen Framework 5.8.

My gateway communicates with the microservices via Guzzle6 Http Client and locally works great. When it is pushed to the cluster using Gitlab to run a ci/cd pipeline to compile it as a docker image and deploy it to Kubernetes on Google Cloud.

I have tried switching between "" and '', I have rewritten the entire code, I have looked over the Guzzle Documentation, I have read many stack overflow questions of similar behaviour in docker

routes

    $router->get('/customers','CustomerController@getAll');
    $router->post('/customers','CustomerController@createCustomer');
    $router->get('/customers/{customer}','CustomerController@getCustomer');
    $router->put('/customers/{customer}','CustomerController@updateCustomer');
    $router->patch('/customers/{customer}','CustomerController@updateCustomer');
    $router->delete('/customers/{customer}','CustomerController@deleteCustomer');

controller

public function updateCustomer(Request $request, $customer)
    {
        return $this->successResponse($this->customerService->updateCustomer($request->all(), $customer));
    }

    public function deleteCustomer($customer)
    {
        return $this->successResponse($this->customerService->deleteCustomer($customer));
    }

service

public function createCustomer($data)
    {
        return $this->performRequest('POST','', $data);
    }

    public function getCustomer($customer)
    {
        return $this->performRequest('GET', "/{$customer}");
    }

    public function updateCustomer($data, $customer)
    {
        return $this->performRequest('PUT', "{$customer}", $data);
    }

    public function deleteCustomer($customer)
    {
        return $this->performRequest('DELETE', "{$customer}");
    }

performRequest

public function performRequest($method, $requestUrl, $formParams = [], $headers = [])
    {
        $client = new Client([
            'base_uri' => $this->baseUri,
        ]);
        $response = $client->request($method, $requestUrl, ['form_params' => $formParams, 'headers' => $headers]);
        return $response->getBody()->getContents();
    }

Endpoints Locally: - GET /contacts WORKS! - POST /contacts WORKS! - GET /contacts/(contacts UUID identifier) WORKS! - PUT/PATCH /contacts/(contacts UUID identifier) WORKS! - DELETE /contacts/(contacts UUID identifier) WORKS!

Endpoints Production: - GET /contacts WORKS! - POST /contacts WORKS! - GET /contacts/(contacts UUID identifier) FAILS! - PUT/PATCH /contacts/(contacts UUID identifier) FAILS! - DELETE /contacts/(contacts UUID identifier) FAILS!

Sentry Bug Tracker shows GuzzleHttp\Exception\RequestException cURL error 3: (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

when looking at the URL on sentry the base URI is getting ignored on the endpoints that are failing but this doesn't happen on my local machine.


Solution

  • The url doesn't contain the protocol(http) adding this will fix the malformed url error.

    Final url: http://customer-microservice.customer-microservice.svc.cluster.local