tuupola / slim-api-skeleton Goto Github PK
View Code? Open in Web Editor NEWSlim 3 API skeleton project for Composer
License: MIT License
Slim 3 API skeleton project for Composer
License: MIT License
I'm encountering an issue at line 16 of App\Token.php
return !!count(array_intersect($scope, $this->decoded->scope));
saying "array_intersect(): Argument #2 is not an array".
I have just cloned your skelton and test it in my laptop and that works fine. i uploaded the skeleton to my cloud with no code modifications but i am getting:
{
"title": "Token not found",
"type": "about:blank",
"status": 401
}
when i send post request to create todos. my request is:
curl "http://mydomain.com/tstapi/public/todos" --request POST --include --insecure --header "Authorization: Bearer $TOKEN" --header "Content-Type: application/json" --data '{ "title": "Test the API", "order": 10 }'
can u please help?
Current below is my settings.php
[ 'displayErrorDetails' => true, // set to false in production 'addContentLengthHeader' => false, // Allow the web server to send the content-length header // Renderer settings 'renderer' => [ 'template_path' => __DIR__ . '/../templates/', ], // Monolog settings 'logger' => [ 'name' => 'slim-app', 'path' => isset($_ENV['docker']) ? 'php://stdout' : __DIR__ . '/../logs/app.log', 'level' => \Monolog\Logger::DEBUG, ], "db" => [ "host" => "localhost", "dbname" => "***", "user" => "***1", "pass" => "***" ], ], ]; With this settings it works perfectly in the route when I called this e.g. $selectQueryResult1 = $this->db->prepare($selectQuery1) The issue now I will want to have many different database e.g. db1, db2; when I set new settings in the settings file I always get this error /var/www/html/apiv1/vendor/slim/slim/Slim/Container.php(172): Slim\Container->get('db1') How can I set and call those extra database settings?Mika,
Got another PHP error:
PHP Strict standards: Declaration of Slim\Handlers\NotAllowed::__invoke() should be compatible with Slim\Handlers\Error::__invoke(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, Exception $exception) in [...]\slim-api-skeleton-master\src\Slim\Handlers\NotAllowed.php on line 10
With Slim 3.8.1 and PHP 5.6
Same context as test that generated a PHP Warning (#21) , but after applied the code patch (I've proposed).
curl request sent is
curl "http://localhost:7000/token"
-H "Host: localhost:7000"
-H "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0"
-H "Accept: */*"
-H "Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3"
--compressed
-H "Authorization: Basic dGVzdDp0ZXN0"
-H "Connection: keep-alive"
through this plugin https://addons.mozilla.org/fr/firefox/addon/rest-easy/
Laurent
Hi there,
I'm trying to set up a basic test environment with on my hosting server. Everything was working fine but I'm suddenly getting a 500 error as indicated in the subject. Do you know what this is?
Thanks!
EDIT: Also, note that this is the second project I'm installing with the host. The first one had no issues at all.
can you add JWT support and URL like
URL/login
URL/register
URL/status //will get all the status only if he is authenticated or 403 error will be thrown
Please provide the database sql file used as example in the project.
First, I would like to say how much I am loving this! I have used this to spin up like 3 APIs now in the blink of an eye. The latest one I am using requires me to have relationships built into my entities and I was wondering if that was possible with this setup? I did it just like it is in the Spot docs....here is my entity class:
namespace App;
use Spot\EntityInterface;
use Spot\MapperInterface;
use Spot\EventEmitter;
use Tuupola\Base62;
use Ramsey\Uuid\Uuid;
use Psr\Log\LogLevel;
class Chat extends \Spot\Entity
{
protected static $table = "chats";
public static function fields()
{
return [
"chat_id" => ["type" => "integer", "unsigned" => true, "primary" => true, "autoincrement" => true],
"chat_event_id" => ["type" => "integer", "unsigned" => true],
"chat_expires_at" => ["type" => "string", "length" => 100],
"chat_created_at" => ["type" => "datetime", "value" => new \DateTime()],
"chat_updated_at" => ["type" => "datetime", "value" => new \DateTime()]
];
}
public static function events(EventEmitter $emitter)
{
$emitter->on("beforeUpdate", function (EntityInterface $entity, MapperInterface $mapper) {
$entity->chat_updated_at = new \DateTime();
});
}
public static function relations(MapperInterface $mapper, EntityInterface $entity)
{
return [
'messages' => $mapper->hasMany($entity, 'App\ChatMessage', 'chat_message_chat_id')->order(['chat_message_created_at' => 'ASC']),
];
}
public function timestamp()
{
return $this->chat_updated_at->getTimestamp();
}
}
and here is my Transformer class for Fractal:
namespace App;
use App\Chat;
use League\Fractal;
class ChatTransformer extends Fractal\TransformerAbstract
{
public function transform(Chat $chat)
{
return [
"chat_event_id" => (integer)$chat->chat_event_id ?: 0,
"chat_expires_at" => (string)$chat->chat_expires_at ?: null,
"chat_messages" => $chat->messages
];
}
}
Everything else is pretty much setup like you do in your examples. When I run this, I only get a blank for the 'chat_messages' return even though I know there should be something in there so I was just wondering if I was missing something.
hello everyone, Can someone help me fix this? I cloned this project and executed, my setup xampp, php 7.2 and apache. Thanks.
I got the following error
Parse error: syntax error, unexpected 'class' (T_CLASS), expecting identifier (T_STRING) or variable (T_VARIABLE) or '{' or '$' in //vendor/slim/slim/Slim/Container.php on line 149
i googled the error and it could be due to php version. the php version installed in my host is 5.4.
what modification i need to make my api compatible with v. 5.4?
Hi Guys,
Firtsly, I'm sorry if I miss placed the question. After weeks learning the framework with this skeleton, I just desperate facing this issue.
It seems I can't run 2 consecutive query using TableGateway. It's always produce (not just UPDATE):
"Statement couldn't be produced with sql: UPDATE `users` SET `last_access` = NOW() WHERE `id` = ?"
Here's the code inside ZendUserRepository:
...
public function footprint(int $id): void {
$data = ['last_access' => new Predicate\Expression('NOW()')];
$where = ['id' => $id];
$this->table->update($data, $where);
}
public function authenticate(string $username, string $password): bool {
$where = [
'username' => $username,
new Predicate\IsNotNull('roles')
];
$rowset = $this->table->select($where);
if (null === $row = $rowset->current()) {
return false;
}
$data = (array) $row;
if(password_verify($password, $data['password'])) {
$this->footprint($data['id']);
return true;
}
return false;
}
...
Please, kindly help this newbie here.
Best Regards,
Adit
I have used Vagrant earlier for building Wordpress sites using VVV or VIP Quickstart. So, I understand the advantages of using vagrant.
But, in this Slim project I am facing some issues understanding my system:
I will really appreciate if you can shed some light on the above.
P.S. your thoughts on building microservices architecture using this framework are welcome.
File ./config/dependencies.php
import Fractal module, but it's not used.
use League\Fractal\Manager as FractalManager;
use League\Fractal\Resource\Item as FractalItem;
use League\Fractal\Serializer\DataArraySerializer;
It is used by TransformTodoService and TransformTodoCollectionService, in their own file.
In my app I need to be able to enable/disable cache in order to check the results.
How can I disable?
Mika,
In file slim-api-skeleton-master\routes\todos.php
,
throw new PreconditionFailedException("Todo has been modified", 412);
As precondition failed, I suppose that the reason should be spelled "Todo has not been modified"
Laurent
When some exceptions are throwed by Slim the ApiError handler can't handle it because the passed parameters are wrong.
Uncaught TypeError: Argument 3 passed to Slim\Handlers\ApiError::__invoke() must be an instance of Slim\Handlers\Exception, instance of UnexpectedValueException given in /home/ieasrl/intranet/src/Slim/Handlers/ApiError.php:19
For example if i upload the project to the server, create a virtualHost and i forgot to give 777 cmod permission to log folder this could happend.
I can't understand what is really wrong or if ApiError must work different. So i have to comment handlers to see the error in apache log.
Other error when handler.php is not commented is:
[Thu Aug 10 10:16:44.159886 2017] [:error] [pid 14888] [client 10.0.2.247:51490] PHP Notice: Array to string conversion in /home/ieasrl/intranet/vendor/tuupola/dbal-psr3-logger/src/Psr3Logger.php on line 40
I'm getting this error
[20-Jan-2018 07:48:02 UTC] PHP Warning: require(/home/avytoqau/api4/vendor/autoload.php): failed to open stream: No such file or directory in /home/avytoqau/api4/app.php on line 20
[20-Jan-2018 07:48:02 UTC] PHP Warning: require(/home/avytoqau/api4/vendor/autoload.php): failed to open stream: No such file or directory in /home/avytoqau/api4/app.php on line 20
[20-Jan-2018 07:48:02 UTC] PHP Fatal error: require(): Failed opening required '/home/avytoqau/api4/vendor/autoload.php' (include_path='.:/opt/alt/php55/usr/share/pear:/opt/alt/php55/usr/share/php') in /home/avytoqau/api4/app.php on line 20
Missing vendor folder?
Thank you for this awesome skeleton-project.
Have you planned to do an update to make it slim 4 compatible and with the (new) best practices ?
I would be highly interested by it.
I received error by function not found: gmp_strval, looking in the internet, for use this function is necessayr install php5-gmp extension and enable it. Please update the readme file, can help others users.
Hi
Haw can i test this with PostMan.
I dont anderstand what do you meen by this:
"--data '["todo.all"]'
--user test:test"
I am sending post request like:
> curl "http://localhost:8888/api/public/token" --include --insecure --header "Content-Type: application/json" --data '["todo.create", "tod.read"]' --user test:test
but i am getting:
ate: Fri, 23 Jun 2017 20:02:50 GMT
Server: Apache
X-Powered-By: PHP/7.1.1
Content-Length: 126
Connection: close
Content-Type: application/problem+json
{
"title": "Insecure use of middleware over HTTP denied by configuration.",
"type": "about:blank",
"status": 500
I use the postman with auth basic authorization and user in headers test and password test with post method and in body of request like scope[] = todo.all and scope[] = todo.list, I received the answer statos => ok and the token. But in other request like /dump or /todos i received the answer "token not found".
I'm getting the following error:
Is it because starting January 22nd, 2018 http-interop is officially deprecated in favor of PSR-15?
Please respond. Require immediate assistance.
I am getting
Syntax error, malformed JSON
my request:
curl "http://localhost:8888/api/public/todos" --request POST --include --insecure --header "Authorization: Bearer $TOKEN" --header "Content-Type: application/json" --data '{ "title": "Test the API", "order": 10 }'
response:
HTTP/1.1 401 Unauthorized
Date: Fri, 23 Jun 2017 20:46:26 GMT
Server: Apache
X-Powered-By: PHP/7.1.1
Content-Length: 93
Content-Type: application/problem+json
{
"title": "Syntax error, malformed JSON",
"type": "about:blank",
"status": 401
Hello Mika,
I've just tested your very nice skeleton.
First thanks to share it !
Second, I've found a little warning raised by PHP that could be catch easily.
When you don't give the scope on curl request you get
PHP Warning: array_filter() expects parameter 1 to be array, null given in [...]\slim-api-skeleton-master\routes\token.php on line 34
Easy FIX will be to add, just after routes\token.php
, line 21 ( $requested_scopes = $request->getParsedBody();
)
if ($requested_scopes === null) {
$requested_scopes = [];
}
Laurent
In let's say to Todo
class, I need to add a property from another table via JOIN
. This works well through the hydrator
, transformer
classes etc. However how do I deal with the CreateQuery
and CreateHandler
classes? It's required to pass the joined property which obviously doesn't exist in the table.
I was able to unset the property in the ZendRepo
but this somehow doesn't feel elegant. Is there any way you recommend to approach this?
Uncaught Error: Class 'Dotenv\Dotenv' not found in /var/www/html/slim-api-skeleton-master/app.php:21
Stack trace:
This is the Error When i try to call the localhost/todo API just for testing
I'm looking at the zend-db
documentation and they indicate that ORDER BY
is achieved with something like:
$select = new Select;
$select->order('id DESC'); // produces 'id' DESC
Your ZendTodoRepository
all
function seems to always expect an array. Was your framework set up with ORDER BY
in mind? How can we achieve this?
If I run any of the examples for example:
curl "https://192.168.50.52/todos" \
--request POST \
--include \
--insecure \
--header "Authorization: Bearer INSERT-JWT-TOKEN-HERE" \
--header "Content-Type: application/json" \
--data '{ "title": "Test the API", "order": 10 }'
Then I get this response
{
"title": "Too few arguments to function Skeleton\\Domain\\Token::__construct(), 0 passed in .../app/config/middleware.php on line 41 and exactly 1 expected",
"type": "about:blank",
"status": 500
}
I'm not sure what I'm doing wrong. I've tried everything including creating the database and adding tables and data for the todo's app.
Thanks
Hi @tuupola! Does it make sense to add psr6 handler (ie redis or memcache) to the psr7 already implemented? The ETAG don't reduce connection .. or I'm wrong? I lost my way ... I think I need to reduce db conns and I think I need to add cache handler into api? Otherwise I still use psr6 for single application with misaligned data! How can I continue in the right way?
Hi there,
Great work on the Skeleton API!
I'm new to Slim API and have been playing around and have duplicated the 'todos' table with an 'entries' table. The GET routing is working fine but I can't POST anything. I get the error 'Call to a member function getTimestamp() on null'.
Debugging this leads me to $entry ($todo in your case) returning null in the following block of code (note that all handlers have been added to the dependencies file:
$command = new CreateEntryCommand($data);
$this->commandBus->handle($command);
$query = new ReadEntryQuery($data);
$entry = $this->commandBus->handle($query); // $entry returns NULL
/* Add Last-Modified and ETag headers to response. */
$response = $this->cache->withEtag($response, $entry->etag());
$response = $this->cache->withLastModified($response, $entry->timestamp());
Here's how the objects look like:
$query:
object(Skeleton\Application\Entry\ReadEntryQuery)#316 (1) {
["uid":"Skeleton\Application\Entry\ReadEntryQuery":private]=>
string(13) "1E3HbNm2aHG7A"
}
$entry:
object(Skeleton\Domain\Entry)#334 (6) {
["uid":"Skeleton\Domain\Entry":private]=>
NULL
["order":"Skeleton\Domain\Entry":private]=>
NULL
["completed":"Skeleton\Domain\Entry":private]=>
bool(false)
["title":"Skeleton\Domain\Entry":private]=>
NULL
["createdAt":"Skeleton\Domain\Entry":private]=>
NULL
["updatedAt":"Skeleton\Domain\Entry":private]=>
NULL
}
$data:
array(3) {
["title"]=>
string(25) "Testtttttttttttty the API"
["order"]=>
int(10)
["uid"]=>
string(13) "1E3HbNm2aHG7A"
}
When I print the $todo object in the todo POST route, I'm successfully getting data instead of NULL.
Do you have any idea why this could be the case?
I am getting 500 internal server error. my host support is saying it is because of
php_value always_populate_raw_post_data -1 in .httaccess file.
what does -1 means? how to fix this issue?
Thanks
Hi,
Reviewing your package for a possible project. What would you recommend in implementing ORM Model data validation for your package?
I know this is not a bug, but really seek your help. i am trying to call this api to generate token. so i wrote php function to perform the call. something like:
ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
but i get authentication failed. this i think because the user/pass should be passed in the form of:
--user test:test.
can you please help
Hi Mika
I'm working with Slim3 and in your example I see an interesting model of design pattern to handle Response PSR-7 as a separated NS (ie /src/response/NotFoundResponse.php). In API apps a lot of controllers run same function with the same response (ie Item, Collection, bad validation, db errors etc.. - Don't Repeat Yourself) and I want to use a global class/trait to handle responses from controllers and I found something in this API skeleton. But I don't understand how to handle Response $response outsite controller. Is it the right way ?
Finally, in your Response NS, all __construct call parent with
$headers = (new Headers)->set("Content-type", "application/problem+json");
but the Http Headers is null; I try to separate it like this
$headers = new Headers();
$headers->set("Content-type", "application/problem+json");
and Http Headers are set correctly. It's a mistake ?
Thank you so much!
An additional argument needs to be added to line 211 in /vendor/tuupola/slim-basic-auth/src/HttpBasicAuthentication.php
To reproduce the error, try to use the wrong username and password in the example curl:
$ curl "https://192.168.50.52/token"
--request POST
--include
--insecure
--header "Content-Type: application/json"
--data '["todo.all"]'
--user NOT_TEST:NOT_TEST
The response is:
"Too few arguments to function {closure}(), 2 passed in /opt/lampp/htdocs/payment/vendor/tuupola/slim-basic-auth/src/HttpBasicAuthentication.php on line 211 and exactly 3 expected"
I was able to "fix" this error by changing line 211 to:
$handler_response = $this->options["error"]('ADDITIONAL ARGUMENT', $response, $arguments);
Of course, based on line 144 the response should be:
"title": "Authentication failed", "type": "about:blank", "status": 401
Hi Tuupola,
I was trying out composer create-project --no-interaction --stability=dev tuupola/slim-api-skeleton app. Then when I tried to run I got this output
<?php
require __DIR__ . "/../app.php";
What else settings can I run to enable it properly? Secondly where should I put the route file now in this new version because in my older version I had everything in src folder both the middleware and routes file?
Hi, i dont know if this is an issue or not. May be i'm doing something wrong, but for example, when i try to login and get a token if the credentials are wrong i throw an exception like NotFoundException
and this is passed to \Slim\Handlers\Error\ApiError
who handle the exception and gives response with a json object. The problem is that Cors information is not at the response header's when this path is taked in the code. How can i fix this. Thanks.
$credentials = $request->getParsedBody();
$mapper = $this->spot->mapper("App\Entities\Auth\User");
// Selecciono el usuario
$result = $mapper->where([
'username' => $credentials['username'],
'password' => md5($credentials['password'])
])->with('perms')->first();
if(!$result){
$data = array("status" => "error", "msg" => "");
if($mapper->where(['username' => $credentials['username']])->first()){
$alert = ["type" => "danger", "message" => "La contraseña es incorrecta"];
}else{
$alert = ["type" => "danger", "message" => "El usuario ingresado no existe."];
}
throw new NotFoundException($alert['message'], 401);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.