Connect Yii2 to another RESTful application - rest

I have a Yii2 application. I would like to connect it to another restful webpage. So user will send data to my application, I will send them via POST request and do something according to a JSON response. How can I do the send a request / fetch response part in a yii2?

The best method would be to use curl to make end to end calls to your RESTful API, in which case you may be interested in checking out a yii2 extension for curl.
Without a Yii2 extension, we can accomplish this by creating a more general function in a controller or more preferably a model (for shared access) as exampled below:
/**
* $method e.g POST, GET, PUT
* $data = [
'param' => 'value',
]
*/
public function curlToRestApi($method, $url, $data = null)
{
$curl = curl_init();
// switch $method
switch ($method) {
case 'POST':
curl_setopt($curl, CURLOPT_POST, 1);
if($data !== null) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
// logic for other methods of interest
// .
// .
// .
default:
if ($data !== null){
$url = sprintf("%s?%s", $url, http_build_query($data));
}
}
// Authentication [Optional]
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "username:password");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
We then call this function on a need basis i.e. depending on the method and url and/or data.
It is also conveniently easy to use file_get_contents if fopen wrapper is enabled in order to access Web Service URLs.
$response = file_get_contents('http://example.com/path/to/api?param1=stack&param2=overflow');
If a JSON response is served, you can recover the php array as follows:
$response = json_decode($response, TRUE);
If an XML response is returned, then
$response = new \SimpleXMLElement($response);
However, if the API endpoint returns an HTTP error status, the file_get_contents function fails with a warning and returns null.

Related

Consume a REST API in codeigniter controller

I have create a REST API and want to consume my own created API in codeigniter controller.
My created REST API
controller(example.php)
class Example extends REST_Controller {
public function __construct() {
parent::__construct();
$this->load->model('user');
}
public function user_fetch_post() {
//returns all rows if the id parameter doesn't exist,
//otherwise single row will be returned
$id = $this->input->post('id');
$users = $this->user->getRows($id);
//check if the user data exists
if(!empty($users)){
//set the response and exit
$this->response($users, REST_Controller::HTTP_OK);
}else{
//set the response and exit
$this->response([
'status' => FALSE,
'message' => 'No user were found.'
], REST_Controller::HTTP_NOT_FOUND);
}
}
model(user.php)
function getRows($id = ""){
if(!empty($id)){
$query = $this->db->get_where('users', array('id' => $id));
return $query->row_array();
}else{
$query = $this->db->get('users');
return $query->result_array();
}
}
Here i want to call my created api(from example.php)for fetch record in welcome.php controller with basic authentication(uname-admin,pwd-1234)
my controller welcome.php
public function index()
{
}
Can anybody help to me that how to call my api in controller welcome.php with basic authentication.
Using CURL you can consume any API/network call.
<?php
$headers = array(
'Content-Type:application/json',
'Authorization: Basic '. base64_encode("user:password") // place your auth details here
);
$payload = array(
'id' => 1,
);
$process = curl_init($host); //your API url
curl_setopt($process, CURLOPT_HTTPHEADER, $headers);
curl_setopt($process, CURLOPT_HEADER, 1);
curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_POST, 1);
curl_setopt($process, CURLOPT_POSTFIELDS, $payload);
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
$return = curl_exec($process);
curl_close($process);
//finally print your API response
print_r($return);
?>
But why are you calling your own API this way? You can simply call your API model and perform your operations
Add below to your curl options
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'APIKEY: admin#123',
'Content-Type: application/json',
));
also update
$config['rest_key_name'] = 'APIKEY';
in rest.php file inside config folder of your codeigniter settings. By default it is 'X-API-KEY'
This may help to somebody else looking for a solution, if OP has resolved it himself/herself.

Laravel rest api authentication

I am a beginner with building a rest api and authentication.
I've just been reading the following and explains a very simple setup:
laravel 5 rest api basic authentication
At the bottom the article explains not to send usernames and password with headers or in the url.
My question is basicly: can anyone give me an example how to use a cUrl request with the example above?
For example:
$service_url = 'http://example.com/api/conversations';
$curl = curl_init($service_url);
$curl_post_data = array(
'user' => 'user#user.com',
'passw' => '1234'
);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
$curl_response = curl_exec($curl);
curl_close($curl);
Laravel is shipped with Guzzle – an advanced HTTP client library. It's probably more reasonable to use that than a low-level cURL.
To do basic auth with Guzzle:
$client = new GuzzleHttp\Client();
$response = $client->post('http://example.com/api/conversations', [
'auth' => [
'user#user.com',
'1234'
]
]);
The response will be in $response->getBody();
If your target endpoint uses SSL – it's not too bad sending the credentials in the headers, but the trendy way is to use temporary tokens (eg. API key or OAuth access token).
In addition to the accepted answer, you can also create a generic function to handle all your curl requests.
You can use the following function to call external webservices and return the data/authentication information.
/*=============================================
* Call External Webservices using CURL
*
* #param $requestURL, $header -> (OPTIONAL)
* #return json
#=============================================*/
public function curlRequest($requestURL, $headers = array())
{
$getData = curl_init($requestURL);
curl_setopt($getData, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($getData, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($getData, CURLOPT_SSL_VERIFYHOST, false);
if (count($headers) != 0) {
curl_setopt($getData, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($getData);
return json_decode($response);
}
Use case specific example to use the above function for authentication:
$requestURL = 'http://www.example.com/api/userLogin';
$userAuthInfo = [
'email'=> 'example#example.com',
'password'=>'123456'
];
$result = $this->curlRequest($requestURL, $userAuthInfo);
dd($result); //Print the Result of the Authentication request

Translate cURL request to Guzzle

I am trying to use Guzzle instead of directly using cURL to achieve and HTTP request. How do I make this same type of request but with Guzzle? Or should I just stick to cURL?
$ch = curl_init();
// Set the URL
curl_setopt($ch, CURLOPT_URL, $url);
// don't verify SSL certificate
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
// Return the contents of the response as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Follow redirects
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
// Set up authentication
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$token:X");
I keep running into 401 Unauthorized error. I know I have correct credentials. What makes me think I am not on the right track is the Guzzle docs stating: auth is currently only supported when using the cURL handler, but creating a replacement that can be used with any HTTP handler is planned. But from my understanding Guzzle defaults with cURL.
$guzzleData = [
'auth' => [$token, 'X'],
'allow_redirects' => true,
'verify' => false,
];
$client = new \Guzzle\Http\Client();
$request = $client->get($url, $guzzleData);
$response = $request->send();
Here is the solution:
$client = new \Guzzle\Http\Client();
$request = $client->get($url);
$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYHOST, false);
$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false);
$request->getCurlOptions()->set(CURLOPT_RETURNTRANSFER, true);
$request->getCurlOptions()->set(CURLOPT_FOLLOWLOCATION, true);
$request->getCurlOptions()->set(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$request->getCurlOptions()->set(CURLOPT_USERPWD, "$token:X");
$response = $request->send();
The solution I was able to get working for Guzzle6 is:
$headers = array();
$headers['grant_type'] = 'client_credentials';
$headers['client_id'] = $clientid;
$headers['client_secret'] = $clientSecret;
$response = $this->client->post($urlAuth, ['form_params' => $headers]);
$output = $response->getBody()->getContents();
ie the header array has to be wrapped in 'form_params'

How can I get product list with its detail in rest API backend is magento2

I'm working on native mobile application backend is magento2 and I want to display product after customer selected a category. I am able to get list of the product by category in rest request but that list don't have much details about the product.
Request : http://localhost/magento2/index.php/rest/V1/categories/24/products
(24 is category ID)
Response : [{"sku":"WH01","position":1,"category_id":"24"},...]
Earlier in Magento 1.9 product list was something like
{
2: {
entity_id: "2"
type_id: "simple"
sku: "Levis Bagpack"
description: "Bagpack"
short_description: "Bagpack"
meta_keyword: null
name: "Levis Bagpack"
meta_title: null
meta_description: null
regular_price_with_tax: 45
regular_price_without_tax: 45
final_price_with_tax: 45
final_price_without_tax: 45
is_saleable: true
image_url: "http://172.16.8.24:8080/magento/media/catalog/product/cache/0/image/9df78eab33525d08d6e5fb8d27136e95/images/catalog/product/placeholder/image.jpg"
}
What should I do to get more info about product so I can show image and other things in mobile app ?
Maybe you can try the GET /V1/products/:sku REST API to get all the details.
Link
The returned value will be a representation of \Magento\Catalog\Api\Data\ProductInterface (including the additional attributes)
Link for Reference
Check \Magento\Catalog\Api\ProductRepositoryInterface::get which services the GET /V1/products/:sku REST API.
You can make multiple requests for all product SKUs.
OR
You can use the search API to fetch the entire list in a single request based on your criteria:
For example:
http://localhost/magento2/index.php/rest/V1/products?searchCriteria[filter_groups][0][filters][0][field]=sku&searchCriteria[filter_groups][0][filters][0][value]=simple&searchCriteria[filter_groups][0][filters][1][field]=sku&searchCriteria[filter_groups][0][filters][1][value]=Simple2&searchCriteria[filter_groups][0][filters][0][condition_type]=eq&searchCriteria[current_page]=1&searchCriteria[page_size]=2
In the case of products with SKUs - simple and Simple2 are being searched.
define('BASEURL','http://localhost/magento20_0407/');
$apiUser = 'testUser';
$apiPass = 'admin123';
$apiUrl = BASEURL.'index.php/rest/V1/integration/admin/token';
/*
Magento 2 REST API Authentication
*/
$data = array("username" => $apiUser, "password" => $apiPass);
$data_string = json_encode($data);
try{
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$token = curl_exec($ch);
$token = json_decode($token);
if(isset($token->message)){
echo $token->message;
}else{
$key = $token;
}
}catch(Exception $e){
echo 'Error: '.$e->getMessage();
}
/*
Get Product By SKU REST API Magento 2
Use above key into header
*/
$headers = array("Authorization: Bearer $key");
//$requestUrl = BASEURL.'index.php/rest/V1/products/24-MB01';//24-MB01 is the sku.
//$requestUrl = BASEURL.'index.php/rest/V1/products?searchCriteria[page_size]=10';// get total 10 products
//$requestUrl = BASEURL.'index.php/rest/V1/categories/24/products';// 24 category id
$requestUrl = BASEURL.'index.php/rest/V1/products?searchCriteria=';//get all products
$ch = curl_init();
try{
$ch = curl_init($requestUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$result = json_decode($result);
if(isset($result->message)){
echo $result->message;
}else{
print_r($result);
}
}catch(Exception $e){
echo 'Error: '.$e->getMessage();
}
Similarly you can change $requestUrl and filter product list by category id and get product detail.
Please confirm whether it solves your problem or not. Else I'll post another solution.
You can try this, where '30' is category id. http://magentohost.com/rest/default/V1/products?searchCriteria[filter_groups][0][filters][0][field]=category_id&%20searchCriteria[filter_groups][0][filters][0][value]=30&%20searchCriteria[filter_groups][0][filters][0][condition_type]=eq&searchCriteria[pageSize]=10
Please try to use this endpoint instead of your endpoint:
/V1/products?searchCriteria[filter_groups][0][filters][0][field]=category_id&searchCriteria[filter_groups][0][filters][0][value]=24&searchCriteria[filter_groups][0][filters][0][condition_type]=eq
It is the same as #Alexander Timonchev, But you have to remove the space after &

CURL communication with Facebook's graph not working

everyone.
I have the following issue:
I'm using curl to get some info from facebook's graph (and this used to work until just a few days ago), but now I just get an empty answer.
The request is quite simple:
https://graph.facebook.com/?ids=XXX&access_token=YYY
The ids parameter is just a list of ids for elements in the graph (in this case, application requests). When I copy/paste the url on a browser, it works, but when using curl it gets stuck without an answer.
The full code for the curl call is:
require 'php/facebook.php';
$facebook = new Facebook(array(
'appId' => 'XXX',
'secret' => 'YYY',
));
$url = "https://graph.facebook.com?ids=".$_POST['data']."&access_token=".$_POST['access_token'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$results = curl_exec($ch);
curl_close($ch);
echo $results;
Could anyone shed some light on this?
Cheers!
try {} graph.facebook.com/ with trailing slash
$url = "https://graph.facebook.com/?ids=".$_POST['data']."&access_token=".$_POST['access_token'];
also i am unsure where you are trying to retrieve the post from so you could try request method instead.
$url = "https://graph.facebook.com/?ids=".$_REQUEST['data']."&access_token=".$_REQUEST['access_token'];
example ajax call to php:
// get albums
function showAlbums(pageid,limit,offset){
thealbums = "albums";
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("albums").innerHTML=xmlhttp.responseText;
}
};
xmlhttp.open("GET","plugins.albums.php?pageid="+pageid+"&limit="+limit+"&offset="+offset+"",true);
xmlhttp.send();
}
Try for cURL:
function GetCH(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://graph.facebook.com?ids=".$_POST['data']."&access_token=".$_POST['access_token']");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT_MS,20000);
if(substr($url,0,8)=='https://'){
// The following ensures SSL always works. A little detail:
// SSL does two things at once:
// 1. it encrypts communication
// 2. it ensures the target party is who it claims to be.
// In short, if the following code is allowed, CURL won't check if the
// certificate is known and valid, however, it still encrypts communication.
curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_ANY);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
}
$sendCH = curl_exec($ch);
curl_close($ch);
return $sendCH;
};
$ThisId = GetCH();
echo $ThisId;