Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial for simple REST API missing file names #2683

Closed
kennykegger opened this issue Aug 6, 2014 · 22 comments
Closed

Tutorial for simple REST API missing file names #2683

kennykegger opened this issue Aug 6, 2014 · 22 comments

Comments

@kennykegger
Copy link

The tutorial for creating a simple REST API with phalcon is missing the filenames so a beginner cannot know which files to copy/paste the various code bits into. The only mention is for index.php. Otherwise we're left to guess and there's no zip to download the source.

http://docs.phalconphp.com/en/latest/reference/tutorial-rest.html

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@shaneparsons
Copy link

+1 for this.. Spent way to much time trying to understand what to do with the following block of code.
I still don't know how it works by the way..

<?php

use Phalcon\Loader;
use Phalcon\DI\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql as PdoMysql;

// Use Loader() to autoload our model
$loader = new Loader();

$loader->registerDirs(
    array(
        __DIR__ . '/models/'
    )
)->register();

$di = new FactoryDefault();

// Set up the database service
$di->set('db', function () {
    return new PdoMysql(
        array(
            "host"     => "localhost",
            "username" => "root",
            "password" => "root",
            "dbname"   => "robots"
        )
    );
});

// Create and bind the DI to the application
$app = new Micro($di);

@shaneparsons
Copy link

Can someone please post some working code in here until the page is updated?

I'm considering using phalcon for an immediate project, but without knowing how to get the REST api functionality to work, I'm going to be forced to use another framework instead.

@andresgutierrez
Copy link
Contributor

What trouble do you have using the code in the tutorial?

@shaneparsons
Copy link

The block of code I pasted above is where my trouble started from as I wasn't sure where to put it.
Seeing as the tutorial recommends the following directory, I decided to put it in index.php.

my-rest-api/
    models/
        Robots.php
    index.php
    .htaccess

Here's my entire index.php

<?php

use Phalcon\Loader;
use Phalcon\Mvc\Micro;
use Phalcon\DI\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql as PdoMysql;
use Phalcon\Http\Response;

/**
 * Configuration
 */

// Use Loader() to autoload our model
$loader = new Loader();

$loader->registerDirs(
    array(
        __DIR__ . '/models/'
    )
)->register();

$di = new FactoryDefault();

// Set up the database service
$di->set('db', function () {
    return new PdoMysql(
        array(
            "host"     => "localhost",
            "username" => "root",
            "password" => "root",
            "dbname"   => "robots"
        )
    );
});

// Create and bind the DI to the application
$app = new Micro($di);


/**
 * API Functions
 */

// Retrieves all robots
$app->get('/api/robots', function () {
  $phql = "SELECT * FROM robots ORDER BY name";
    $robots = $app->modelsManager->executeQuery($phql);

    $data = array();
    foreach ($robots as $robot) {
        $data[] = array(
            'id'   => $robot->id,
            'name' => $robot->name
        );
    }

    echo json_encode($data);
});

...

$app->handle();

EDIT
Im getting this error:

Fatal error: Uncaught exception 'Phalcon\Mvc\Micro\Exception' with message 'Not-Found handler is not callable or is not defined' in /Applications/MAMP/htdocs/samples/phalcon/rest/index.php:249 Stack trace: #0 /Applications/MAMP/htdocs/samples/phalcon/rest/index.php(249): Phalcon\Mvc\Micro->handle() #1 {main} thrown in /Applications/MAMP/htdocs/samples/phalcon/rest/index.php on line 249

@andresgutierrez
Copy link
Contributor

You can place the code in index.php, for tutorial purposes it would be fine place it there, however, as long as your application evolves it can be moved out to more files. Take this structure as example: https://github.com/phalcon/dasshy

@shaneparsons
Copy link

Any idea what's causing that Fatal error?

@andresgutierrez
Copy link
Contributor

You have to access one of the routes defined in the example, for instance: /api/robots, if you aren't using nginx or a virtualhost, make sure you have a .htaccess file: https://github.com/phalcon/dasshy/blob/master/public/.htaccess

@shaneparsons
Copy link

Yeaa sorry about that, I figured that out earlier.. it's this error that I cant figure out

Notice: Undefined variable: app in /Applications/MAMP/htdocs/samples/phalcon/rest/index.php on line 52

Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/samples/phalcon/rest/index.php on line 52

Fatal error: Call to a member function executeQuery() on null in /Applications/MAMP/htdocs/samples/phalcon/rest/index.php on line 52

Line 52 being $robots = $app->modelsManager->executeQuery($phql);

@andresgutierrez
Copy link
Contributor

This line must be fixed:

$app->get('/api/robots', function () use ($app) {

@shaneparsons
Copy link

Ah shit, sorry about that.. I was copying & pasting from the tutorial so I'm not quite sure how that happened.

thanks

@peteroruba
Copy link

I am also having a hard time making the tutorial run.
curl -i -X GET http://localhost/my-rest-api/api/robots
leads to the following Apache error:

[pid 9708] [client 127.0.0.1:51196] PHP Fatal error: Uncaught exception 'Phalcon\Di\Exception' with message 'Service 'db' wasn't found in the dependency injection container' in /var/www/index.php:37\n
Stack trace:\n
#0 [internal function]: Phalcon\Di->get('db', NULL)\n
#1 [internal function]: Phalcon\Di->getShared('db')\n
#2 [internal function]: Phalcon\Mvc\Model\Manager->_getConnection(Object(Robots), NULL)\n
#3 [internal function]: Phalcon\Mvc\Model\Manager->getReadConnection(Object(Robots))\n
#4 [internal function]: Phalcon\Mvc\Model->getReadConnection()\n
#5 [internal function]: Phalcon\Mvc\Model\MetaData\Strategy\Introspection->getMetaData(Object(Robots), Object(Phalcon\Di\FactoryDefault))\n
#6 [internal function]: Phalcon\Mvc\Model\MetaData->_initialize(Object(Robots), 'robots-robots', 'robots', '')\n
#7 [internal function]: Phalcon\Mvc\Model\MetaData->readMetaData(Object(Robots))\n
#8 [internal function]: Phalcon\Mvc\Model\MetaData->hasAttribute(Object(Robots), 'name')\n
#9 [internal function]: Phalcon\Mvc\Model\Query->_getQualified(Array)\n
#10 [internal function]: Phalcon\Mvc in /var/www/index.php on line 37

The missing file names in the tutorial were causing me headache as well.

@williamokano
Copy link

Are you injecting the db to the Dependency Injector?

On Thu, Sep 17, 2015 at 11:25 AM peteroruba [email protected]
wrote:

I am also having a hard time making the tutorial run.
curl -i -X GET http://localhost/my-rest-api/api/robots
leads to the following Apache error:

[pid 9708] [client 127.0.0.1:51196] PHP Fatal error: Uncaught exception
'Phalcon\Di\Exception' with message 'Service 'db' wasn't found in the
dependency injection container' in /var/www/index.php:37\n
Stack trace:\n
#0 [internal function]: Phalcon\Di->get('db', NULL)\n
#1 #1 [internal function]:
Phalcon\Di->getShared('db')\n
#2 #2 [internal function]:
Phalcon\Mvc\Model\Manager->_getConnection(Object(Robots), NULL)\n
#3 #3 [internal function]:
Phalcon\Mvc\Model\Manager->getReadConnection(Object(Robots))\n
#4 #4 [internal function]:
Phalcon\Mvc\Model->getReadConnection()\n
#5 #5 [internal function]:
Phalcon\Mvc\Model\MetaData\Strategy\Introspection->getMetaData(Object(Robots),
Object(Phalcon\Di\FactoryDefault))\n
#6 #6 [internal function]:
Phalcon\Mvc\Model\MetaData->_initialize(Object(Robots), 'robots-robots',
'robots', '')\n
#7 #7 [internal function]:
Phalcon\Mvc\Model\MetaData->readMetaData(Object(Robots))\n
#8 #8 [internal function]:
Phalcon\Mvc\Model\MetaData->hasAttribute(Object(Robots), 'name')\n
#9 #9 [internal function]:
Phalcon\Mvc\Model\Query->_getQualified(Array)\n
#10 #10 [internal function]:
Phalcon\Mvc in /var/www/index.php on line 37

The missing file names in the tutorial were causing me headache as well.


Reply to this email directly or view it on GitHub
#2683 (comment).

@peteroruba
Copy link

Looking at the error message I guess I am not. I copied&pasted the tutorial source code to index.php and Robots.php.

@williamokano
Copy link

$di = new FactoryDefault();

// Set up the database service
$di->set('db', function () {
return new PdoMysql(
array(
"host" => "localhost",
"username" => "root",
"password" => "root",
"dbname" => "robots"
)
);
});

// Create and bind the DI to the application
$app = new Micro($di);

@peteroruba
Copy link

Thank you, William, for your help. Indeed, I had
$app = new Micro();
instead of
$app = new Micro($di);

Now the error is:
[:error] [pid 3851] [client 127.0.0.1:50470] PHP Fatal error: Uncaught exception 'Phalcon\Mvc\Model\Exception' with message 'Model 'robots' could not be loaded' in /var/www/index.php:37\n
Stack trace:\n
#0 [internal function]: Phalcon\Mvc\Model\Manager->load('robots', true)\n
#1 [internal function]: Phalcon\Mvc\Model\Query->_prepareSelect()\n#2 [internal function]: Phalcon\Mvc\Model\Query->parse()\n
#3 [internal function]: Phalcon\Mvc\Model\Query->execute()\n
#4 /var/www/index.php(37): Phalcon\Mvc\Model\Manager->executeQuery('SELECT * FROM r...')\n
#5 [internal function]: {closure}()\n
#6 /var/www/index.php(239): Phalcon\Mvc\Micro->handle()\n
#7 {main}\n thrown in /var/www/index.php on line 37

I had to manually create the table ( create table robots (id INT, name varchar(100)); ) and correct all references in the source code to lower case (working on Linux and wanted to avoid case sensitivity issues)

@andresgutierrez
Copy link
Contributor

Do you have a class like:

class robots extends \Phalcon\Mvc\Model
{
}

?

@peteroruba
Copy link

I have this model delcaration, again, just copied & pasted from the tutorial into models/Robots.php

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Message;
use Phalcon\Mvc\Model\Validator\Uniqueness;
use Phalcon\Mvc\Model\Validator\InclusionIn;

class Robots extends Model
{
public function validation()
{
// Type must be: droid, mechanical or virtual
$this->validate(
new InclusionIn(
array(
"field" => "type",
"domain" => array(
"droid",
"mechanical",
"virtual"
)
)
)
);
// Robot name must be unique
$this->validate(
new Uniqueness(
array(
"field" => "name",
"message" => "The robot name must be unique"
)
)
);
// Year cannot be less than zero
if ($this->year < 0) {
$this->appendMessage(new Message("The year cannot be less than zero"));
}
// Check if any messages have been produced
if ($this->validationHasFailed() == true) {
return false;
}
}
}

(Sorry for the bad formatting)

@peteroruba
Copy link

Alright, I have everything working now. It was a case sensitivity issue which needed to be fixed a several lines ("Robots" class, "robots" MySQL table name).

From a beginner's point of view I would suggest the following updates to the tutorial:

  1. In addition to explaining what code fragment gets added for which functionality, provide all files with their final content. The process of assembling them from the fragments was very error prone to me and in total it took me several hours to get this tutorial running.
  2. Eliminate case sensivity issues.
  3. Provide the SQL statements to create the database.

Once again, thank you for your help, William & Andres

@mutazhameed
Copy link

hi,
i'm still having this error:
Fatal error: Uncaught exception 'Phalcon\Mvc\Model\Exception' with message 'Model 'robots' could not be loaded'
in C:\new\xampp\htdocs\projects\index.php:47
Stack trace:

#0 [internal function]: Phalcon\Mvc\Model\Manager-&gt;load('robots', true)
#1 [internal function]: Phalcon\Mvc\Model\Query-&gt;_prepareSelect()
#2 [internal function]: Phalcon\Mvc\Model\Query-&gt;parse()
#3 [internal function]: Phalcon\Mvc\Model\Query-&gt;execute()
#4 C:\new\xampp\htdocs\projects\index.php(47): Phalcon\Mvc\Model\Manager-&gt;executeQuery('SELECT * FROM r...')
#5 [internal function]: {closure}()
#6 C:\new\xampp\htdocs\projects\index.php(90): Phalcon\Mvc\Micro-&gt;handle()
#7 {main}

thrown in C:\new\xampp\htdocs\projects\index.php on line 47

my files:
Robots.php

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Message;
use Phalcon\Mvc\Model\Validator\Uniqueness;
use Phalcon\Mvc\Model\Validator\InclusionIn;

class Robots extends \Phalcon\Mvc\Model
{
    public function validation()
    {
        // Type must be: droid, mechanical or virtual

        // Robot name must be unique
        $this->validate(
            new Uniqueness(
                array(
                    "field"   => "name",
                    "message" => "The robot name must be unique"
                )
            )
        );

        // Year cannot be less than zero
        if ($this->year < 0) {
            $this->appendMessage(new Message("The year cannot be less than zero"));
        }

        // Check if any messages have been produced
        if ($this->validationHasFailed() == true) {
            return false;
        }
    }
}

index.php

use Phalcon\Loader;
use Phalcon\Mvc\Micro;
use Phalcon\DI\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql as PdoMysql;
use Phalcon\Http\Response;

// Use Loader() to autoload our model
$loader = new Loader();

$loader->registerDirs(
    array(
        __DIR__ . '/models/'
    )
)->register();

$di = new FactoryDefault();

// Set up the database service
$di->set('db', function () {
    return new PdoMysql(
        array(
            "host"     => "localhost",
            "username" => "root",
            "password" => "",
            "dbname"   => "api-one"
        )
    );
});

// Create and bind the DI to the application
$app = new Micro($di);


// Retrieves all robots
$app->get('/api/robots', function () use ($app) {

    $phql = "SELECT * FROM robots ORDER BY name";
    $robots = $app->modelsManager->executeQuery($phql);

    $data = array();
    foreach ($robots as $robot) {
        $data[] = array(
            'id'   => $robot->id,
            'name' => $robot->name
        );
    }

    echo json_encode($data);
});


$app->notFound(function () use ($app) {
    $app->response->setStatusCode(404, "Not Found")->sendHeaders();
    echo 'This is crazy, but this page was not found!';
});

$app->handle();

.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L]
</IfModule>

mysql table scheme:

Database: api-one
Table structure for table robots

CREATE TABLE `robots` (
  `id` int(11) NOT NULL,
  `name` int(250) NOT NULL,
  `type` varchar(250) NOT NULL,
  `year` varchar(250) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

and i have the rewrite_mod on, any clue what might cause the error??
thank you in advance
ps. when i echo __DIR__ . '/models/' it outputs "C:\PATH-TO-HTDOCS\robots/models/" shouldn't be "C:\PATH-TO-HTDOCS\robots/app/models/" !!

@mutazhameed
Copy link

okay i fixed it, turns out the problem is with model path, i just moved models folder to root dir and works fine, now have another error:
Notice: Trying to get property of non-object in C:\new\xampp\htdocs\projects\index.php on line:77
{"status":"ERROR","messages":["name is required","type is required","year is required"]}

any help?

UPDATE:
when i var_dump $robot in $robot = $app->request->getJsonRawBody(); i get NULL

@CedricArnouldEM6
Copy link

I made the tuto too, and it is not possible to Insert or Update a robot

Same error as mutazhameed , getJsonRawBody is always null.

Can someone help us?

@sergeyklay
Copy link
Contributor

This is Phalcon Docs issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants