My first attempt with REST API


(Ngothean1) #1

Hi there:
I just started with Yii2 REST.
I follow step by step the tutorial
rest quick start

This is what I did, step-by-step

  1. Create the database yii2basic

  2. Create the table user
    CREATE TABLE yii2basic.user (
    id INT NOT NULL,
    name VARCHAR(45) NULL,
    PRIMARY KEY (id));

  3. Insert some data
    mysql> insert into user (id,name) values (1,“AAA”),(2,“BBB”),(3,“CCC”);

  4. Create basic template
    $ composer create-project --prefer-dist yiisoft/yii2-app-basic rest

  5. Then using gii to create the model
    models/User.php

  6. Change config/web.php as suggested in the tutorial: urlManager, parser

Then I perform the following tests as suggested

  1. browser
    http://myyii2.rest/users
    OK it shows all users
  2. CURL
    $ curl -i -H “Accept:application/json” “http://myyii2.rest/users
    OK
  3. Postman GET myyii2.rest/users
    OK
  4. Add a new user (4,“DDD”) using Postman POST myyii2.rest/users
    OK
  5. Add a new user (5,“EEE”) using CURL
    curl -i -H “Accept:application/json” -H “Content-Type:application/json” -XPOST “http://myyii2.rest/users” -d ‘{“id” : “5”, “name” : “EEE”}’
    OK
  6. But when I test
    GET users/1
    I get this result
    “The requested URL /users/1 was not found on this server”
    Same problem with PUT, DELETE

What did I do wrong?
Thank you very much
Andy


#2

can you show the exact curl command you try and the exact output?


(Ngothean1) #3

Hi CeBe:

I redo from start with myyii2.app

Blockquote
$ composer create-project --prefer-dist yiisoft/yii2-app-basic app
There were a lot of “suggestions” such as
sebastian/global-state suggests installing ext-uopz (*)
but I did not do anything.

$ sudo chmod -R 777 app

In mysql
CREATE TABLE user (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) NOT NULL,
auth_key varchar(32) NOT NULL,
password_hash varchar(255) NOT NULL,
email varchar(100) NOT NULL,
status smallint(10) NOT NULL,
created_at int(11) NOT NULL,
updated_at int(11) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE country (
code char(2) NOT NULL,
name char(52) NOT NULL,
population int(11) NOT NULL DEFAULT ‘0’,
PRIMARY KEY (code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Add some data into the table country.

Change app/config/db.php

Go to browser
myyii2.api/index.php?r=gii
generate models
app/models/User.php
app/models/Country.php

add
app/controls/UserController.php
app/controls/CountryController.php

change app/config/web.php

Blockquote

This is the results with curl

Blockquote
andy@andy-Inspiron-15-3567:~/websites$ curl -i -X OPTIONS “http://myyii2.app/countries
HTTP/1.1 200 OK
Date: Sat, 10 Nov 2018 22:23:57 GMT
Server: Apache/2.4.29 (Ubuntu)
Allow: GET, POST, HEAD, OPTIONS
Access-Control-Allow-Methods: GET, POST, HEAD, OPTIONS
X-Debug-Tag: 5be75a7dd4088
X-Debug-Duration: 6
X-Debug-Link: /debug/default/view?tag=5be75a7dd4088
Content-Length: 0
Content-Type: application/json; charset=UTF-8

andy@andy-Inspiron-15-3567:~/websites$ curl -i “http://myyii2.app/countries
HTTP/1.1 200 OK
Date: Sat, 10 Nov 2018 22:24:52 GMT
Server: Apache/2.4.29 (Ubuntu)
X-Pagination-Total-Count: 16
X-Pagination-Page-Count: 1
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: http://myyii2.app/countries?page=1; rel=self
X-Debug-Tag: 5be75ab4c3e8c
X-Debug-Duration: 7
X-Debug-Link: /debug/default/view?tag=5be75ab4c3e8c
Content-Length: 837
Content-Type: application/json; charset=UTF-8

[{“code”:“A1”,“name”:“Aaaaaaa1”,“population”:1000},{“code”:“A2”,“name”:“A2”,“population”:2000},{“code”:“AU”,“name”:“Australia”,“population”:24016400},{“code”:“B1”,“name”:“B1”,“population”:1000000},{“code”:“B2”,“name”:“B2”,“population”:2000000},{“code”:“BR”,“name”:“Brazil”,“population”:205722000},{“code”:“CA”,“name”:“Canada”,“population”:35985751},{“code”:“CN”,“name”:“China”,“population”:1375210000},{“code”:“DE”,“name”:“Germany”,“population”:81459000},{“code”:“FR”,“name”:“France”,“population”:64513242},{“code”:“GB”,“name”:“United Kingdom”,“population”:65097000},{“code”:“IN”,“name”:“India”,“population”:1285400000},{“code”:“LA”,“name”:“Laos”,“population”:20000000},{“code”:“RU”,“name”:“Russia”,“population”:146519759},{“code”:“US”,“name”:“United States”,“population”:322976000},{“code”:“VN”,“name”:“Vietnam”,“population”:100000000}]

andy@andy-Inspiron-15-3567:~/websites$ curl -i -H “Accept:application/json” -H “Content-Type:application/json” -XPOST “http://myyii2.app/countries” -d ‘{“code” : “B3”, “name” : “B3”, “population” : “3000000”}’
HTTP/1.1 201 Created
Date: Sat, 10 Nov 2018 22:25:44 GMT
Server: Apache/2.4.29 (Ubuntu)
Location: http://myyii2.app/country/view?id=B3
X-Debug-Tag: 5be75ae8d814d
X-Debug-Duration: 50
X-Debug-Link: /debug/default/view?tag=5be75ae8d814d
Content-Length: 48
Content-Type: application/json; charset=UTF-8

{“code”:“B3”,“name”:“B3”,“population”:“3000000”}

andy@andy-Inspiron-15-3567:~/websites$ curl -i “http://myyii2.app/countries/A1
HTTP/1.1 404 Not Found
Date: Sat, 10 Nov 2018 22:26:23 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Length: 286
Content-Type: text/html; charset=iso-8859-1

404 Not Found

Not Found

The requested URL /countries/A1 was not found on this server.


Apache/2.4.29 (Ubuntu) Server at myyii2.app Port 80

Blockquote

This is the apache2 config file
myyii2.app.conf

Blockquote
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request’s Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com

ServerAdmin ngothean1@gmail.com
ServerName myyii2.app
ServerAlias www.myyii2.app
DocumentRoot /home/andy/websites/app/web

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

<Directory  /home/andy/websites/app/web/>
		# use mod_rewrite for pretty URL support
		RewriteEngine on
		# If a directory or a file exists, use the request directly
		RewriteCond %{REQUEST_FILENAME} !-f
		RewriteCond %{REQUEST_FILENAME} !-d
		# Otherwise forward the request to index.php
		RewriteRule . index.php

		# if $showScriptName is false in UrlManager, do not allow accessing URLs with script name
		RewriteRule ^index.php/ - [L,R=404]
	
	Options Indexes FollowSymLinks MultiViews
		AllowOverride all
		Require all granted
	
</Directory>
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf

Blockquote

Thank you very much


(Ngothean1) #4

Sorry, the format was a bit messed up. Don’t know how to visualize before posting.


(Ngothean1) #5

Hi there:
I replied in the forum but it was a bit messy.

So I copied the curl part here:

(I just redo step by step with just another name myyii2.app to make sure that I follow exactly the guide)

andy@andy-Inspiron-15-3567:~/websites$ curl -i -X OPTIONS “http://myyii2.app/countries

HTTP/1.1 200 OK


#6

In yii\rest\UrlRule, the ID of an element is assumed to be integer by default:

https://www.yiiframework.com/doc/api/2.0/yii-rest-urlrule#$tokens-detail

if your contry ID can contain other characters than numbers, you need to configure url rule accordingly:

'urlManager' => [
   'enablePrettyUrl' => true,
   'enableStrictParsing' => true,
   'showScriptName' => false,
   'rules' => [
       ['class' => 'yii\rest\UrlRule', 'controller' => 'user',
           // this needs to be added here to allow non-integer IDs
           'tokens' => [
               '{id}' => '<id:.+>', // .+ is a regular expression that allows any character
          ]
       ],
   ],
]

if you have a more concrete restriction on the characters allowed in the ID you can replace the regex with that definition.


(Ngothean1) #7

Hi there:
Thank you for your response. However, the problem is not solved yet. Even when I use the exact database user with numeric id. I always receive the same message.
Do you want me to send the whole source code?
Thank you


(Ngothean1) #8

It seems that it doesn’t recognise the pattern countries/
I added a country with code 11

This command will give the list of countries
$ curl “http://myyii2.basic/countries
However, all these commands
$ curl “http://myyii2.basic/countries/
$ curl “http://myyii2.basic/countries/11
$ curl “http://myyii2.basic/countries/A1

will give the same result

404 Not Found

Not Found

The requested URL /countries/11 was not found on this server.


Apache/2.4.29 (Ubuntu) Server at myyii2.basic Port 80

Thanks
Andy


(Ngothean1) #9

Hi there:

I went through many yii2 rest template in GitHub

Like this one:
yii2-rest

One thing I observed is that
$ composer global require “fxp/composer-asset-plugin:~1.0.0”

However, mine is 1.4.4

I wonder if this that difference can break my application.
I remember that about 3 years ago, I already installed yii2 rest without any problem (I didn’t touch that application for a long time and my computer having that application was lost)