Getting values sent using post method in controller in magento 2 api - php

I can not get values sent from post method, using http request.
I am getting values using get method, but I need to get it using post method.
I am not using any view, I want to call http url, and send some data in my controller using post method.
This is how my controller looks like,
namespace Spaarg\eMenuApi\Controller\Index;
class Products extends \Magento\Framework\App\Action\Action
{
public function __construct(\Magento\Framework\App\Action\Context $context)
{
return parent::__construct($context);
}
public function execute()
{
//$token = $this->getRequest()->getPostValue();
$token = $this->getRequest()->getPost();
}
}
I am new to magento 2, and I don't understand what is the problem.
It will be great if someone can help.

It probably has to do with the Content-type of the http request, where Magento only understands Json and Xml (this is explained here). If you're using a different Content-type in the request or your data doesn't match the type declared in the header, then getPost() will not work.
As a fallback, you can always get all the POST data by using the following way:
public function execute()
{
$postData = file_get_contents("php://input");
}
Keep in mind that this will get the raw string, so you will likely need to process it accordingly before using it (for example with json_decode() or something like that).
For more information about this, check this SO question.

Related

What is the correct method to pass parameter to Laravel controller for filtering data?

This is my code of route for getting data from Laravel backend.
Route::get('/get/card',[CardController::class,'getCardList'])->name('card.list');
I call it like below,
http://127.0.0.1:8000/get/card
Controller code
public function getCardList()
{
//code goes here
}
The above code is working fine. I'm trying to add a parameter for adding filtration as follows;
Route::get('/get/card{treeItemID?}',[CardController::class,'getCardList'])->name('card.list');
public function getCardList($treeItemID)
{
}
http://127.0.0.1:8000/get/card?treeItemID=1
But, I'm getting the error "Too few arguments to function app\Http\Controllers\CardController::getCardList()..."
Can anyone notice what's wrong with my code that gives the above error when the parameter is added? Any help would be highly appreciated.
if you want to get data like below url, please replace your route and method like below and check again.
http://127.0.0.1:8000/get/card?treeItemID=1
Route::get('/get/card',[CardController::class,'getCardList'])->name('card.list');
public function getCardList(Request $request){
$treeItemID = $request->input('treeItemID');
return $treeItemID;
}
You can use get and post both type of request for filtering purpose.
Scenario 1 => If you want to hide some parameter inside request then you can use POST type of request where use can pass data in form data and get from request inside in controller.
Route::post('/get/card',[CardController::class,'getCardList'])->name('card.list');
public function getCardList(Request $request){
$treeItemID = $request->treeItemID;
return $treeItemID;
}
Scenario 2 => If you do want to hide some parameter inside the request then you can use GET type of request where use can pass data in url and get from request or get from parameter url inside in controller.
Route::get('/get/card/{treeItemID}',[CardController::class,'getCardList'])->name('card.list');
public function getCardList($treeItemID){
$treeItemID = $treeItemID;
return $treeItemID;
}

Do all API responses need to explicitly be returned with a json function?

I'm getting into api controllers and am wondering if this index function:
public function index()
{
$data = DB::table('galleries')->get();
return response()->json($data);
}
inside my api controller has to be returned with response()->json() or if it is OK to just return the variable:
public function index()
{
$data = DB::table('galleries')->get();
return $data;
}
Both seem to work. Are there reasons to use the former one?
the return $data will just convert the $data into a json response. no header will be set and your frontend will not recognize it as a json object.
return response() will return a full Response instance. from the doc
Returning a full Response instance allows you to customize the response's HTTP status code and headers. A Response instance inherits from the Symfony\Component\HttpFoundation\Response class, which provides a variety of methods for building HTTP responses
for return response()->json() method
The json method will automatically set the Content-Type header to application/json, as well as convert the given array to JSON using the json_encode PHP function
so this will be recognised as json object in your frontend. Read more at laravel doc.
When you send something as a response which is not already an instance of a Response then Laravel will create a new instance of a Response with that as the content. When the response is sent and that object is an array (or arrayable) or something that is convertible to JSON then it is sent as a JSON response. At that point all relevant headers will be correct.
There are two parts of the source code to consider if you are curious on how this works:
The part that checks whether the response is already an instance of Response and constructs one if not
The part that decides whether a response content should be JSON
If you want my opinion then you should be doing response()->json(...) which creates a JsonResponse instance that has no chance to be ambiguous because otherwise you are relying on undocumented behavior which is subject to change.
Both seem , both are correct but if you send as json it will be formal and in the fornt-end site they can use easily

Codeigniter RESTful services routing

I am trying to integrate RESTful services to my Codeigniter application. I am using this library https://github.com/chriskacerguis/codeigniter-restserver and the tutorial from https://code.tutsplus.com/tutorials/working-with-restful-services-in-codeigniter--net-8814.
However, I am a little confused about how to implement routing. The tutorial mentions using the full url but I'd like to do something like:
My Controller
class AdminLogin_WS extends REST_Controller {
public function __construct() {
parent::__construct();
$this->load->model('AccountModel');
}
public function login_get(){
$this->response(json_encode(null));
}
public function login_post(){
$username = $this->post('username');
$this->response(json_encode($username));
}
}
My routes
$route['AdminLogin_WS/Login']['post']= 'AdminLogin_WS/login_post'; <= this will trigger an unknown method error
$route['AdminLogin_WS/Login']= 'AdminLogin_WS/login'; <= this will call the get function
REST Request
public function ws_login(){
$this->curl->create('https://url.com/AdminLogin_WS/Login');
$this->curl->http_login('login','password');
$this->curl->post(array(
'username' => 'auser'
));
$result = $this->curl->execute();
var_dump(json_decode($result));
}
How can I specify what function is a post or get?
You can specify is a function is post or get by using _post() and _get() respectively.
For your routing, I think you are routing wrongly. There should be a difference between the main route and the alternate route. You should have something like
$route['method/param1'] = 'controller/method/param1';
Updated with information from chat
Using login_get() and login_post() and then making the POST request to AdminLogin_WS/login was the correct thing to do, and the login_post() was getting called, there was just some confusion because the POST was returning the same response as the GET using the code that the poster was using.
Original answer
I would post this as a comment but don't have the rep to do so.
What do you mean by "It only works if I create a controller function called login_get()"? That sounds to me like you're sending in a GET rather than a POST to your route. Can you give some information on how you're testing to see if you can POST and get to your login_post()? Have you tried downloading a tool like Postman (https://www.getpostman.com/) and sending in a POST to help eliminate the possibility that you're not sending in the POST correctly?

CakePHP 2.x - Accessing $_POST data within controller (REST POST request)

I'm creating an API using Cakephp 2.x that needs a POST request to post some data to the server however when I'm posting (using Postman) to 127.0.0.1/appname/api/confirm with code=123 in the post parameters my $_POST is an empty array.
My route works, I can see variables that I declare and output within the controller, and I've checked that the parameters are being passed in the request by using the chrome developer console checking the network data.
Router::connect('/api/confirm', array('controller' => 'awesomeController', 'action' => 'confirm'));
<?php
class AwesomeController extends AppController {
public function confirm() {
$this->autoRender = false;
$this->layout = 'ajax';
pr($_POST);
}
}
?>
I've got my endpoints for the get requests to work just fine, it only seems to be POST data.
Not quite sure why $_POST wouldn't even be available and I'm sure it's something ridiculously silly I've overlooked!
** Edit **
I've attempted the following without success:
$this->request->query
$this->request->data
$this->request->params
I have another method whereby I use GET along with ?parameter=value etc and I am able to use one of the above calls to retrieve the data.
In this case, the variables should be in
$this->request->query
Try using URLs like api/confirm?code=123, and they will be in request->query
I may be wrong since I am pretty new to cakePHP but since you set:
$this->autoRender = false;
so the view is not rendered automatically to set the view to ajax layout.
Isn't it necessary to call:
$this->render();
After setting the layout as said here?
Well, hope it helps.
If anybody come here one day by googling, just had the same problem.
Had a REST Controller, called with URL /rest/something/cool.json
Method called inside RestController.php, had output, but no POST, no REQUEST.
Tried with code=123, sending direct JSON, the only way to make it works was to set Content-Type to application/json and to send actual working JSON : Cake seems to validate prior to anything, sending raw data seems useless.

Can't get JSON input for Laravel4 POST

I am using Laravel routes to build a RESTful API. I am routing to a Controller. In it, my function "store()" (my post function) should be getting a JSON input and I'm testing it by simply returning it. I seem to be able to see the data being passed in by doing Input::get('data') but I can't do a json_decode on that. The value of the json_decode is simply null. Can anyone help me get a working example of POSTing to a route with JSON data and accessing the data?
Here's what I have:
Route
Route::post('_api/tools/itementry/items', 'ItemEntryController');
Controller
class ItemEntryController extends BaseController
{
//... other functions
public function store()
{
if(Input::has('data'))
{
$x = Input::get('data');
$data = json_decode($x);
var_dump($data);
}
}
}
I'm using a REST tester client to submit a post with the following Query string parameters:
Name: "data"
Value: { itemNumber:"test1", createdBy:"rsmith" }
This ended up being a really stupid problem. I was doing everything right, except my JSON that I was sending in the test client was formatted incorrectly. I forgot to add quotes around the key strings.
So, instead of doing { itemNumber:"test1", createdBy:"rsmith" }
I needed to do { "itemNumber":"test1", "createdBy":"rsmith" }
Now it works.

Categories