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();;
}