I would like to build an API that does a GET request to a third party API. I created a controller that houses this logic and registered this as an HTTP end point using the JsonApiRoute::server() facade. I am absolutely new to Laravel and PHP.
However when I run php artisan serve I get the error:
Server /api/v1 does not exist in config or is not a valid class.
This is my code in routes:
JsonApiRoute::server('/api/v1')
->prefix('/api/v1')
->resources(function ($server) {
$server->resource('retrieve');
});
This is the code I have in config-> json-api-default:
return [
'resolver' => \CloudCreativity\LaravelJsonApi\Resolver\ResolverFactory::class,
'namespace' => null,
'by-resource' => true,
'model-namespace' => null,
'resources' => [
'posts' => \App\Post::class,
],
'use-eloquent' => true,
'url' => [
'host' => null,
'namespace' => '/api/v1',
'name' => 'api:v1:',
],
'controllers' => [
'transactions' => true,
'connection' => null,
],
'jobs' => [
'resource' => 'queue-jobs',
'model' => \CloudCreativity\LaravelJsonApi\Queue\ClientJob::class,
],
'encoding' => [
'application/vnd.api+json',
],
'decoding' => [
'application/vnd.api+json',
],
'providers' => [],
];
and in my controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class retrieve extends Controller
{
//
public function retrieveData(Request $request){
$response = Http::withHeaders([
'api-key' => '***',
])->get('https://data.mongodb-api.com/app/data-pkrpq/endpoint/getRandom');
return response()->json(['status'=> true,'data'=> json_decode($response->body()), 'Message'=>'Successfully retrieved'], 200);
}
}
Related
Good morning,
I dont get any further in this Topic so i am writing a Question here.
First of all i created a DB Table with Data from the Tutorial: https://www.yiiframework.com/doc/guide/2.0/en/start-databases
Then i created a Rest Controller from that Tutorial with the Data above: https://www.yiiframework.com/doc/guide/2.0/en/rest-quick-start
The first example GET Request from the Tutorial works fine and gives me all of the data from the DB.
My Request URL: http://XX.X.X.12:XX90/country/
Now we come to my Error when trying to create a new Country in the DB via a POST Request.
When using the CURL Command from underneath the Tutorial with my Test-Data i get following error:
SQLSTATE[HY000]: General error: 1364 Field 'code' doesn't have a default value**strong text**
(
[0] => HY000
[1] => 1364
[2] => Field 'code' doesn't have a default value
)
My standard logging from rest api says that the POST Var is empty, but why?
I also tested sending POST Request via a Tool (Postman) but i get the same error.
$_GET = []
$_POST = []
$_FILES = []
$_COOKIE = []
$_SERVER = [....]
My Model:
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Country extends ActiveRecord
{
}
My Controller:
<?php
namespace app\controllers;
use yii\rest\ActiveController;
class CountryController extends ActiveController
{
public $modelClass = 'app\models\Country';
}
My CURL Request:
curl -i -H "Accept:application/json" -H "Content-Type:application/json" \
-XPOST "http://XX.X.X.12:XX90/countries/" \
-d '{"code": "TEST", "name": "TestCountry", "population": 01}'
My web.php Config:
<?php
$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'aliases' => [
'#bower' => '#vendor/bower-asset',
'#npm' => '#vendor/npm-asset',
],
'name' => 'Yii2-ExtJS Rest API',
'modules' => [
'user' => [
'class' => Da\User\Module::class,
// ...other configs from here: [Configuration Options](installation/configuration-options.md), e.g.
'administrators' => ['admin'], // this is required for accessing administrative actions
// 'generatePasswords' => true,
// 'switchIdentitySessionKey' => 'myown_usuario_admin_user_key',
],
'debug' => [
'class' => 'yii\debug\Module',
'allowedIPs' => ['XX.X.X.XXX', 'XX.XXX.XXX.XXX', '127.0.0.1', '::1']
],
],
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'XXXXXXXXXXXXXXXX',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => \yii\symfonymailer\Mailer::class,
'viewPath' => '#app/mail',
// send all mails to a file by default.
'useFileTransport' => true,
],
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
// 'levels' => ['error', 'warning', 'trace', 'info'],
],
],
],
'db' => $db,
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => false,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => 'country'],
],
],
],
'params' => $params,
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
'allowedIPs' => ['XX.X.X.XX', '::1'],
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
}
return $config;
Suggestions?
You need to declare validation rules for working with the Rest API
Thanks to #Bizley
My Country Model now:
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Country extends ActiveRecord
{
public function rules()
{
return [
[['code', 'name', 'population'], 'required']
];
}
}
I registered a ServiceProvider with easysms
app\Providers\EasySmsServiceProvider.php
<?php
namespace App\Providers;
use Overtrue\EasySms\EasySms;
use Illuminate\Support\ServiceProvider;
class EasySmsServiceProvider extends ServiceProvider{
public function register(){
$this->app->singleton(EasySms::class, function($app){
return new EasySms(config('easysms'));
});
$this->app->alias(EasySms::class, 'easysms');
}
}
then, I add it to config/app.php in providers
config/app.php
'providers' => [
...
// easysms
App\Providers\EasySmsServiceProvider::class,
],
I already checked bootstrap/cache/services.php and I am sure I registered it successful.
But when I try to use it in Controller, errors occurred, it seems like something wrong with EasySmsServiceProvider
here is my controller
app\Http\Controllers\V1\Auth\VerifySmsesController.php
<?php
namespace App\Http\Controllers\V1\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\V1\Auth\VerifySmsRequest;
use Overtrue\EasySms\EasySms;
use Illuminate\Support\Str;
use Cache;
class VerifySmsesController extends Controller{
public function store(VerifySmsRequest $request, EasySms $easySms){
$phone = $request->phone;
$code = str_pad(random_int(1, 999999), 6, 0, STR_PAD_LEFT);
try {
$result = $easySms->send($phone, [
'template' => config('easysms.gateways.aliyun.templates.register'),
'data' => [
'code' => $code
],
]);
} catch (\Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
$message = $exception->getException('aliyun')->getMessage();
abort(500, $message ?: 'Errors In Sending SMS');
}
$key = 'verify_code_' . Str::random(15);
$expiredAt = now()->addMinutes(5);
Cache::put($key, ['phone' => $phone, 'code' => $code], $expiredAt);
return response()->json([
'key' => $key,
'expired_at' => strtotime($expiredAt->toDateTimeString()),
],201);
}
}
here is my routes/api.php
<?php
Route::group([
'prefix' => 'v1',
'name' => 'v1.',
'namespace' => 'V1'
], function(){
Route::group([
'prefix' => 'auth',
'name' => 'auth.',
'namespace' => 'Auth',
'middleware' => ['throttle:'.config('api.rate_limits.sign')]
], function(){
Route::resource('verify-smses', 'VerifySmsesController', ['only' => ['store']]);
});
});
I had try commands below to clear/reset my config, but nothing helps
php artisan config:clear
php artisan clear-compiled
composer dump-autoload
php artisan optimize
also when I try to use $result = app('easysms')->send(...) instead of $result = $easySms->send(...) above
still errors
I am using Laravel 7.8.1.
How can I fix these errors? Thanks a lot~
---update---
config/easysms.php
<?php
use \Overtrue\EasySms\Strategies\OrderStrategy;
return [
'timeout' => 10.0,
'default' => [
'strategy' => OrderStrategy::class,
'gateways' => [
'aliyun',
],
],
'gateways' => [
'errorlog' => [
'file' => '/tmp/easy-sms.log',
],
'aliyun' => [
'access_key_id' => env('SMS_ALIYUN_SMS_ACCESS_KEY_ID'),
'access_key_secret' => env('SMS_ALIYUN_SMS_ACCESS_KEY_SECRET'),
'sign_name' => env('SMS_ALIYUN_SMS_SIGN_NAME'),
'templates' => [
'register' => env('SMS_ALIYUN_SMS_TEMPLATE_REGISTER')
]
],
],
];
---update---
it works when I run code below in php artisan tinker directly
$sms = app('easysms');
try {
$sms->send($phone, [
'template' => config('easysms.gateways.aliyun.templates.register'),
'data' => [
'code' => 1234
],
]);
} catch (\Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
$message = $exception->getException('aliyun')->getMessage();
dd($message);
}
I am having a problem getting Redis caching working in my ZF3 application.
I have been trying to piece together how to do this from various websites, including SO and am really not sure if I am going the right way about this.
What I am doing so far is this:
In my global.php config file I have added :
...
'redis_cache' => [
'adapter' => [
'name' => 'redis',
'options' => [
'server' => [
'host' => '127.0.0.1',
'port' => 6379,
]
]
],
]
...
In my controller I have
use Zend\Cache\StorageFactory;
and then inside a method I am trying to test the cache using
$redis = StorageFactory::factory ($this->config['redis_cache']);
if ($redis->hasItem ('mykey'))
{
$value = $redis->getItem('mykey');
}
echo 'value = ' . $value;
This is not getting the value. However if I do a print_r() on $redis I can see the Redis object has been created.
In case it is of help to anyone else, this is the solution I found.
Firstly, I needed to install zend-serializer, I already had zend-cache installed.
php composer require zendframework/zend-serializer
Then in /config/autoload/global.php I added
'caches' => [
'RedisCache' => [
'adapter' => [
'name' => Redis::class,
'options' => [
'server' => [
'host' => '127.0.0.1',
'port' => '6379',
],
],
],
'plugins' => [
[
'name' => 'serializer',
'options' => [
],
],
],
],
],
In /config/application.config.php I added
'service_manager' => [
'factories' => [
\Zend\Cache\Storage\Adapter\Redis::class => InvokableFactory::class
]
]
Finally, In my controller factory I set up the dependency injection like this
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$cache = $container->get('RedisCache');
return new IndexController($cache);
}
To use the caching in my controller I added the caching to my constructor
public function __construct($cache)
{
$this->cache = $cache;
}
and in a method:
$this->cache->setItem('foo', 'bar');
echo $this->cache->getItem('foo');
I'm using zf-rest for building my RESTful web apps. I have the following configurations:
'zf-rest' => [
Resource\FeedbackResource::class => [
'listener' => Resource\FeedbackResource::class,
'route_name' => 'api/rest/feedback',
'entity_http_methods' => [
],
'collection_http_methods' => [
'POST',
],
],
],
'zf-content-validation' => [
Resource\FeedbackResource::class => [
'use_raw_data' => false,
'allows_only_fields_in_filter' => true,
'POST' => Resource\FeedbackResource::class . '\\Validator',
],
],
'input_filter_specs' => [
Resource\FeedbackResource::class . '\\Validator' => [
Resource\FeedbackResource::PARAM_NAME => $inputFilterSpecForStrings,
Resource\FeedbackResource::PARAM_EMAIL => $inputFilterSpecForStrings,
],
],
Then I created the resource with the corresponding method:
class FeedbackResource extends AbstractResourceListener
{
public function create($data)
{
// do something
}
}
I posted a json string to the endpoint and everything works fine so far. But what I'm wondering about is that I will get $data as an object with the json data as attributes. I expected to get an assoziative array. Is this possible?
I am trying to do something very simple a REST response using json format.
I created a simple model:
Model
<?php
namespace app\models;
use Yii;
use yii\db\ActiveRecord;
class Post extends ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'posts';
}
public function rules()
{
return [
[['title', 'content'], 'required'],
];
}
}
And a simple controller:
Controller
namespace app\controllers;
use Yii;
use yii\rest\ActiveController;
class PostsController extends ActiveController
{
public $modelClass = "app\models\Post";
}
?>
It is the configuration of my web.php file:
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [
'request' => [
'cookieValidationKey' => 'wcHYBrv4bXfLJYnWzrpJz_5vARaAeE9U',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'enableStrictParsing' => false,
//'showScriptName' => false,
'rules' => [
'class' => 'yii\rest\UrlRule',
'controller' => 'posts',
]
],
Other attributes...
The most important part (I think so) is the urlManager configuration, maybe I am missing something but I don't know where is the error below.
The error
When I execute a request with method GET, everything is Ok, but with any other method it fail. It is the error:
{
"name": "Method Not Allowed",
"message": "Method Not Allowed. This url can only handle the following request methods: GET, HEAD.",
"code": 0,
"status": 405,
"type": "yii\web\MethodNotAllowedHttpException"
}
I want to get a simple response like this guy got in this video I just did the same configuration, step by step.
Thank you.
UPDATE
There is more information, when I using Postman, I got this Headers result.
I don't understand why only ALLOW -> GET, HEAD
It is the Body result:
Try this configuration:
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'post'],
],
],
See config and full list of available requests in official docs.
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'author',
'pluralize' => false
],
],
],
When I have to do something like that, I have it a little different. Try to change class in urlManager to "yii\rest\UrlRule"
Exemple (this code works for me ) :
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => [
'post']
]
],
]
Now try to acces to this url POST frontend.dev/basic/web/post whit Postman
namespace app\controllers;
use Yii;
use yii\rest\ActiveController;
class PostsController extends ActiveController
{
public $modelClass = "app\models\Post";
//uncomment actions allowed
public function actions()
{
$actions = parent::actions();
// unset($actions['create']);
// unset($actions['update']);
// unset($actions['delete']);
// unset($actions['view']);
// unset($actions['index']);
return $actions;
}
//setup verb allowed
protected function verbs()
{
return [
'create' => ['POST'],
'update' => ['PUT', 'PATCH', 'POST'],
'delete' => ['DELETE'],
'view' => ['GET'],
'index' => ['GET'],
];
}
}
or setup in config file
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['post', 'user', 'etc', 'etc2'],
'pluralize' => false,
'extraPatterns' => [
'POST' => 'create', // 'xx' refers to 'actionXx'
'PUT {id}' => 'update',
'PATCH {id}' => 'update',
'DELETE {id}' => 'delete',
'GET {id}' => 'view',
'GET {count}' => 'index',
],
],
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
],