I’m writing a Laravel API that consumes an already existing API. I need my own “middleman” API since it inserts sensitive data before sending the request because I don’t want to store that sensitive data on the client side.
I can fetch the data alright and all that, but I would like to be able to use route parameters to access various “dimensions” of the returned JSON object.
Currently, if I navigate to /get/status
I get a response that looks like this.
{ "fuelAmount": 8, "fuelAmountLevel": 11, "tyrePressure": { "frontLeftTyrePressure": "Normal", "frontRightTyrePressure": "Normal", "rearLeftTyrePressure": "Normal", "rearRightTyrePressure": "Normal", "timestamp": "2020-05-19T20:10:49+0000" }, "heater": { "seatSelection": { "frontDriverSide": false, "frontPassengerSide": false, "rearDriverSide": false, "rearPassengerSide": false, "rearMid": false }, "status": "off", "timer1": { "time": "17:30", "state": false }, "timer2": { "time": "00:00", "state": false }, "timestamp": "2020-05-19T11:28:19+0000" }, }
What I would like to be able to do is navigate to get/status/fuelAmount
and only get the fuelAmount back. So I would only get 8
as a response. Currently I am able to do this, but I am not sure how to do this on multiple levels in an efficient way. Because getting the fuelAmount is just one “level deeper”, I also wanna be able to do /get/status/heater/timer1/time
and only get 17:30
as the response.
Currently the code looks like this
public function vehicleGet($vMethod, $dataKey= null) { $response = Http::withHeaders([ // bunch of headers needed to successfully request data ]) ->withBasicAuth("user", config('app.mySecret')) ->get($this->url); if(isset($dataKey)) { return $response[$dataKey]; }else { return $response->json();; } }
The route in Laravel
Route::get("get/{vMethod}/{dataKey?}", "DashController@vehicleGet")->where('dataKey', '.*');
So like I said, if I go to /get/status/heater
I successfully request the status
endpoint of the 3rd-party API and I am able to print out only the heater
data.
{ "seatSelection": { "frontDriverSide": false, "frontPassengerSide": false, "rearDriverSide": false, "rearPassengerSide": false, "rearMid": false }, "status": "off", "timer1": { " time": "17:30", " state": false }, "timer2": { "time": "00:00", "state": false }, "timestamp": "2020-05-19T11:28:19+0000" }
But if I go to /get/status/heater/timer1/
I get Undefined index: heater/timer1
because obviously that key doesn’t exist in the initial JSON object.
So I would have to somehow add more keys to this return statement return $response[$dataKey]
depending on the dataKey
parameter in the URL. I can explode that string and get an array with each individual key but I still need to somehow add each key to the return statement..
I can add more parameters in the route instead of using a single wildcard parameter but then I need to write a bunch of if statements for each of the optional parameters, check if it is set and if it is, use it as a key when displaying the JSON data?
Advertisement
Answer
Replace your current isset
code block with the following:
if(isset($dataKey)) { $dt = $response; $searchFound = 1; $dataKey = explode("/" , $dataKey); foreach($dataKey as $key => $val) { if(isset($dt[$val])) { $dt = $dt[$val]; } else { $searchFound = 0; break; } } return $dt; }else { return $response->json();; }