Problem getting response content using Delphi, Indy10 and LARAVEL PHP - php

I am building a LARAVEL PHP API in order to be consumed by Delphi 2007.
Basically, in Delphi I am performing a POST and in PHP I am validating the fields. If it fails validation, I need to return code 422 along with the validation errors (array).
In Delphi, I'm using Indy10. In it I have a Client of type TIdHTTP.
To do the POST, I do:
Client.Post(sFullEndPoint, Request, Response);
To get code 422:
Client.ResponseCode;
To get the content of the response:
Response.DataString;
In PHP, if I return only one array of errors, as return $ errors I can handle it in Delphi with Response.DataString, the problem is that I won't know the response code, because it will come 200.
If I return response ($ errors, 422) in PHP, Delphi does not find the value of $errors in response.
I need to get the HTTP code and the response body. Can someone help me?

you can set http response code in php like (refrence : https://www.php.net/manual/en/function.http-response-code.php) :
http_response_code(422);
also in laravel you can do it like :
return response('Your output string', 200)->header('Content-Type', 'text/plain');
but i suggest you to pass response as json and add some information about what is wrong or ... :
$errors = [
[
'error_code'=>1312,
'error_message'=>'name is empty'
]
];
return Response::json($errors, 201); // Status code here

Related

How to get HTTP status answer from GuzzleHttp response by php Laravel?

I develop at php Laravel.
I receiving GuzzleHttp response from Mailgun as Object and can't to get from it the status.
the Object is:
O:8:"stdClass":2:{s:18:"http_response_body";O:8:"stdClass":2:{s:6:"member";O:8:"stdClass":4:{s:7:"address";s:24:"test_of_json-4#zapara.fr";s:4:"name";s:10:"not filled";s:10:"subscribed";b:1;s:4:"vars";O:8:"stdClass":0:{}}s:7:"message";s:36:"Mailing list member has been created";}s:18:"http_response_code";i:200;}
I need just last data pair:
"http_response_code";i:200;
to get it into variable, like:
$http_response_code = 200;
or even just its value.
To get string as I cited above I use
$result_ser = serialize($result);
but yet can't to extract value of variable.
Also I tried this:
$this->resultString .= \GuzzleHttp\json_decode($result_ser, true);
and get error.
Please, explain me , How to get/extract value I needed?
To take the response status code you can use the function getStatusCode :
$response = $client->request();
$statusCode = $response->getStatusCode();
while to take the body of response you can use :
$contents = $response->getBody()->getContents();
let's consider your request is something like
$response = $client->get("https://example.com");
if ( $object_res->getStatusCode() == 200 ) { // here you are checking your http status code
}
$object_res->getStatusCode() is the method to get http status code.
refer docs, there is simple example in this page.
I found that 'mailgun/mailgun' package uses its own HTTP client which also uses 'RestClient' and these classes are return stdObject.
In that Object there is property 'http_response_code' containing HTTP response code like 200, 400, 401 etc.
This property accessible by standard way $object->property and it's a solution of my query in this case.
For anybody who will read this question and answers I should to explain one thing that I not cleared in question.
I made request to the Mailgun API for subscribing member to mailing list. The API returns stdObject, not JSON or XML data.
But also there is one more strange thing - stdObject returned when request is successful only. If request fails you'll get just Exception thrown with message and without code. This forced me, if fail, to parse message body instead of get and resolve error code.
$responseObj->getStatusCode();

Symfony json response is returning content twice

I have been writing an API using Symfony as the backend, a plugin written by a third party is sending certain data to an endpoint, the endpoint is then to return a json encoded response, however following the instructions as set out in the current symfony documaentation(https://symfony.com/doc/current/components/http_foundation.html) the return value is displayed twice and the response is not well formed and outputs like string
The original method that I wrote had calls to a database to validate a token, store a bookmark and display the result of the backend process, however when getting down to brass tacks and removing everything but the response building; it is obvious that this is where the problem lies. The method uses this snippet, though for clarity I have not included the database processing and used the posted values as the return array, the result is the same if it is the post or processed data, the output displays twice.
$token = $request->request->get('token');
$bookmark = $request->request->get('bookmark');
$data = ['token' => $token, 'bookmark' => $bookmark];
$response = new Response();
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->setContent(json_encode($data));
$response->send();
return $response;
What I was expecting was a single json response but what is returned is a double string of the json output
e.g. if I posted these values to the above snippet:
token: ksjdbvqpi8e7rqp7evbprb
bookmark: http://www.google.com
the return result is
{"token":"ksjdbvqpi8e7rqp7evbprb", "bookmark":"http:\/\/www.google.com"}{"token":"ksjdbvqpi8e7rqp7evbprb", "bookmark":"http:\/\/www.google.com"}
when what I was expecting was just
{"token":"ksjdbvqpi8e7rqp7evbprb", "bookmark":"http:\/\/www.google.com"}
I have no idea at the moment why it is displaying twice, any help is as always appreciated.
Thanks
$response->send(); is the line that should be removed.
As you already return object of class Response symfony will take care to output this response to browser, you don't need to do it manually with send().

Laravel forcing json response for api

I'm building an api at my company using laravel.
The problem I'm encountering is that if you send an api request without defining the correct header with the request you will get html back if there is a failure e.g. authorization failure or findOrFail() failure.
My thinking is that you never want to return html (even if the user has the wrong header).
I have a couple of solutions. In BeforeMiddleware.php I can manually insert a header into the request such as:
// Check if we are on an api route
$apiRoute = strncmp($uri, '/api/', 5) == 0;
// Insert the request header to force json response
if ($apiRoute){
$language = $request->header->add('Accept', 'application/json');
}
The 2nd solutions would be to throw an error if they don't have the correct header.
What would be the best way to enforce a json response, what is a good practice for handling api responses in laravel?
Once you detected that you are on your api path you are out of the woods and can indeed tackle your problem in the app\Exceptions\Handler.php file like suggested on How do you force a JSON response on every response in Laravel?.
For an open source project I created JSON exception objects by Microsoft format as output, but you can choose the jsonapi format (http://jsonapi.org/examples/#error-objects-basics) as you like:
https://github.com/StadGent/laravel_site_opening-hours/blob/develop/app/Exceptions/Handler.php
(note that on this implementation it is indeed depending from the headers, but you can use your path detection I think)

Laravel with Angularjs Validating json requests bad response

My webapp has Laravel as backend framework which provides a Restful API and in the fronend Angularjs is running.
I send different requests through the api and receive the responses and based on the code of response and data included, appropriate messages are shown to user.
Recently when I send requests using PUT method or POST method, when the data has problem in validation process and Laravel should respond with a 422 code in JSON format, instead I receive a text/html response with code 200. and then everything goes wrong.
This does not happen on my local machine, Only when I test the app in production environment this happens.
I also tested UnAuthorized response which is sent with 403 code, and it works flawlessly.
I tested both the automatic validation error for Laravel (as described in documentation: When using the validate method during an AJAX request, Laravel will not generate a redirect response. Instead, Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.) and also using the following method:
return response()->json(compact('errors'),422);
I should mention that I use following methods to send AJAX requests:
function save(data, url) {
return $http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/json'},
data: angular.toJson(data)
});
}
function update(data, url) {
return $http({
method: 'PUT',
url: url + data.id,
headers: {'Content-Type': 'application/json'},
data: angular.toJson(data)
});
}
needless to say I became totally confused!
UPDATE: It seems to be a problem with Laravel validation process. when the validation runs, request become erroneous. see the following piece of code:
public function altUpdate(Request $request){
$this->authorize('editCustomer', $this->store);
if (!$request->has('customer')){
return response()->json(["message"=>"Problem in received data"],422);
}
$id = $request->customer['id'];
$rules = [
'name' => 'required',
'mobile' => "required|digits:11|unique:customers,mobile,$id,id,store_id,$this->store_id",
'phone' => 'digits_between:8,11',
'email' => "email|max:255|unique:customers,email,$id,id,store_id,$this->store_id",
];
//return response()->json(["problem in data"],422); //this one works properly if uncommented
$validator = Validator::make($request->customer,$rules);
if ($validator->fails()){
$errors = $validator->errors()->all();
Log::info($errors);
return response()->json(["problem in data"],422);//this one is received in client side as a text/html response with code 200
}
$customer = Customer::find($id);
$customer->update(wrapInputs($request->all()));
if ($request->tags) {
$this->syncTags($request->tags, $customer);
}
$message = "Customer updated successfully!";
return response()->json(compact('message'));
}
I still don't know what's the problem of validation process. this code is working on my local machine without any problems but on the production server problem occurs.
I finally got that.
I had added a language file and the file was encoded in UTF-8-BOM, when I converted that file to UTF-8 without BOM things become correct.
the file was resources/lang/[the language]/validation.php and because of the encoding problem the headers were being sent while processing this file.
This question also helped me to find the problem:
Laravel redirect::route is showing a message between page loads

Response::json() doesn't return anything with Nginx + laravel 4

I have an API in Laravel 4 which returns response in JSON format.
return Response::json(array('users' => $users ));
But I am getting a blank response while calling this api endpoint from Angular or Postman. I can see the 'Content-Type' is set to 'text/html'. It is returning json response as 'text/html'.
After searching on web, most people suggested to add json in mime.types file, I have checked /etc/nginx/mime.types and it already contains
application/json json;
The same thing is returning proper response when running with Apache.
Also when I am running this api call from entering the url in browser, it is returning proper response.
Is there anyone else encounter this kind of problem ?

Categories