I need to use an api in my website frontend, but I don't want to expose that api's key to my frontend users, so I've decided to make a proxy. However, I don't think I've necessarily done it in the most clean, straight-forward, Laravel-like or Guzzle-like way. I'll show my work:
In web.php I added a route that looks like this: Route::post('/address-api/{path?}', 'Controller@addressApi')->where('path', '.*');
That way, the entire path after /address-api
is passed to my controller, so I can proxy hypothetically ANY post request to that api.
Then in Controller.php
I've done this:
public function addressApi($path, Request $request)
{
if (!Str::startsWith($path, '/')) $path = '/' . $path; // make sure it starts with /
$url = 'https://api.craftyclicks.co.uk/address/1.1' . $path;
$postData = $request->all();
$postData['key'] = env('CRAFTYCLICKS_KEY');
$client = new Client();
$response = $client->request('POST', $url, [
'json' => $postData
]);
return response()->json(json_decode($response->getBody(), true));
}
So, whatever json they post to my api, I post to the CraftyClicks api, but I add our secret key to the json. The code above is working, it just doesn't seem like the right way to do it.
The thing I'm not sure about is json_decoding the body and returning it, return response()->json(json_decode($response->getBody(), true));
. I feel like there's something... dirty about this. I feel like there must be a cleaner way to return the actual API response exactly as it came in.
At first I was doing return $response->getBody();
, but I didn't like that because it didn't have the Content-type: application/json
header in the response when I did it that way. Does Guzzle provide, out of the box, a way of just returning their response entirely as-is, headers and all?
CodePudding user response:
Let Laravel have the output; this is cleaner.
return response($response->getBody())
->withHeaders($response->getHeaders());