flameart / restyii2
Yii 2 RESTful template
This package's canonical repository appears to be gone and the package has been frozen as a result.
Installs: 109
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 1
Forks: 0
Open Issues: 0
Type:project
Requires
- php: >=7.0.0
- ext-http: *
- codemix/yii2-excelexport: *
- firebase/php-jwt: *
- flameartlab/migration: *
- thamtech/yii2-ratelimiter-advanced: *
- yiisoft/yii2: ~2.0
- yiisoft/yii2-authclient: *
- yiisoft/yii2-swiftmailer: ~2.0 || ~2.1
Requires (Dev)
- codeception/base: ^2.4
- codeception/verify: ~1.0
- yiisoft/yii2-debug: ~2.1
- yiisoft/yii2-faker: ~2.0
- yiisoft/yii2-gii: ~2.1
This package is auto-updated.
Last update: 2023-12-26 19:03:49 UTC
README
Fast prototyping backend starter for SPA applications and mobiles. All main features for a modern app installed and configured.
Features:
- JSON-based CRUD requests, similar to GraphQL, with infinity relations deep
- Generate models and REST controllers for all tables in one click via Gii
- Generate Typescript ORM imports
- Performance optimized
- Signup and Authentication
- Google, Facebook and other third-party oauth-client ready
- Roles system by default, correct work with guests
- Customizable access rules for each field in a table per user role
- Rate limiter: anti-bruteforce, anti-scraper and anti-ddos for specified controllers, by default installed for auth module only (but better to use nginx)
- Trees full support via Materialized Path paradigm
- Automatic migrations: FlameArt Advanced migration generator tool included, can generate migration for tables and data automatically
Getting started
Install steps
-
Install to folder projectName
composer create-project --prefer-dist --remove-vcs --stability=dev flameart/restyii2 projectName cd projectName php init --env=Development --overwrite=All
For release on production just replace env to
--env=Production
, and usecomposer update
instead ofcomposer create-project
-
Configure you DB settings in
/common/config/main-local.php
-
Init migrations
php yii migrate --interactive=0 php yii migrate --migrationPath=@yii/rbac/migrations --interactive=0 php yii install/init
Now system works. You can setup domain for it and check: http://yourdomain/site/index
Create REST automatically
- Create your tables in Database
- Open http://yourdomain/gii/restgen (working only in dev mode)
- Select tables, click Preview and then Generate
- Or you can just run
yii gii/restgen --tableName=* --interactive=0 --overwrite=1
- it make all models and controllers
- Or you can just run
- System automatically create:
- Controllers in
/rest/controllers/api/
- Configurable models for tables in
/common/models/DB/
, which extends classic ActiveRecord models - Classic ActiveRecord models in
/common/models/DB/models
. No need change this, that will be rebuilded after changing columns or relations. Use only configurable models
- Controllers in
- Done! Check you REST http://yourdomain/api/v1/TABLENAME/index - for select first 20 rows
Work with REST
I have javascript module with predefined methods: https://github.com/FlameArt/rest, or you can manually compound JSON-requests with next methods
Get data from DB
- Endpoint: http://yourdomain/api/v1/TABLENAME/index
- POST/GET
- Format: JSON
Typically use, get 2 specified columns for active users with sort by username and pagination: POST http://yourdomain/api/v1/user/index
{
fields: ["username", "phone"],
where: {"status": 'ACTIVE'},
sort: "username",
page: 1
}
- If
fields
not set - show all fields, accessible for current user - If
where
,sort
not set - without filters or sort - If
page
,per-page
not set - page 1 and 20 rows per page by default
All-featured request with comments:
{
... Your select fields. Field "user" here have a Foreign key, so you just write all fields what you need from related table:
fields: {"id":"", "title":"", "user":
{
"name": "",
"phone": "",
... you can do infinity deep if columns have foreign keys, also here an array format with just field list ...
"country": ["code", "shortname"]
}
},
where: {
... WHERE status=5
"status": 5,
... Yii2 format for custom conditions, example:
"searchText": {"LIKE", "title", "some text"},
... FullText search (match - against):
"searchByFulltextIndex": {"FULLTEXT", "column", "some text"},
... and you can combine multiply AND & OR, details Yii2 format: https://www.yiiframework.com/doc/guide/2.0/en/db-query-builder#where
},
}
Find in MySQL JSON-fields
App supports search JSON-fields in SQL with JSON_CONTAINS
(equivalent OR) for each element in array (MySQL 5.7+)
{
where: [
json_field: [1,3,5]
]
}
Delete items
ACCESS_RULES
can use next values for delete
rule:
*
- no rules, any user can delete any rowself
- user can remove own rows (comparing$USER_ATTRIBUTE
of current table and user id)function($model, $data)
- you can configure you own access checking for delete rowsnull
ordelete
section do not exists - user can't remove rows
Trees
Realized via fast Materialized Path. It compound all tree via 1 query. But you can use NestedTree or other paradigm.
Create migration php yii migrate/create addTreeColumns
like this (items
- your table):
$this->addColumn('items', 'm_tree', $this->integer()->defaultValue(null));
$this->addColumn('items', 'm_path', $this->string(500)->defaultValue(null));
$this->addColumn('items', 'm_depth', $this->integer()->defaultValue(null));
$this->addColumn('items', 'm_sort', $this->integer()->defaultValue(null));
$this->createIndex('path', 'items', ['path']);
And migrate php yii migrate
.
Now, you can append next parameters to query in Create
or Edit
requests:
appendTo=0
for new tree or root itemappendTo=123
append new or edited item to other item with primaryKey 123 as last elementinsertAfter=123
move (or add new) node with this primaryKey in position after other nodeinsertFirst=123
move node as first element of parent node with primaryKey 123
Delete request remove ELEMENT AND ALL CHILDS by default. For save childs for any purposes:
withoutChildrens
for remove a node without childs (they will moved to parent of deleted node)
Read trees
For populate a tree just add to request tree
param with primary key of root node like this:
{
"tree": 123
"where": {"status":1},
}
123
in example - is the primaryKey (id
) for node, which you need to get all it childrens
As you see, you can use all other params like where, fields etc. Response has additional field m_parent
with primary Key of parent node for each column
Populate all tree for current user
{"tree":0}
Gii autogenerator
Auto-generate table models and typescript imports:
-
Via web interface:
- Go http://yourdomain/gii/restgen
- Select multiply tables
- Preview and Generate
-
Via command line for update ALL tables:
yii gii/restgen --tableName=* --interactive=0 --overwrite=1
Typescript ORM models at rest/TSImports/
Безопасность доступа к данным
В отличие от ручной настройки сущностей для каждого запроса, в данном шаблоне настраиваются ограничения на таблицы для каждого юзера, какие поля он может видеть и изменять, а так же используется и классическая схема с RBAC для описания более глобальных уровней доступа. Это позволяет продолжать прогать только фронтенд и запрашивать из него только те поля, что нужны, а система будет лишь проверять возможность доступов к этим полям. Это позволяет настроить бек только 1 раз, в чём и состоит его изначальная задумка, сохраняя уровень безопасности.
Self
field param: it comparing $USER_ATTRIBUTE
of model with current User ID.
Default field name for User ID in DB configured to user
, so if you use other field name, change $USER_ATTRIBUTE
in the model. For example, User
model checks with id
(user can view or edit only self settings)
Signup and auth
Social
Note: signup and auth via socials working only on real domain
You need to fill hostInfo
in /rest/config/main.php
-> requests
with your site domain
Also, you need to register your apps in services and get Client ID
and Secret key
, then write it in /rest/config/main.php
-> authClientCollection
Small instructions how to get these keys:
- Facebook:
- Go https://developers.facebook.com/apps/
- Create App, type: login via FB
- Fill redirect_uri: https://YOURDOMAIN/auth/social?authclient=facebook
- For fields
public_profile
andemail
get Advanced Access (in Permissions tab) - Confirm agreements in Data use checkup
- Google
- Go to https://console.cloud.google.com/apis/credentials
- Create project
- Create Credentials => OAuth Client ID
- Fill redirect_uri: https://YOURDOMAIN/auth/social?authclient=google
Emails
Firstly, you need to configure smtp-account for email, the reason: smtp-mailing is more secure and trustable option, than native clients, which sent emails directly to spam folder, and 2nd: you can disable unsafe proc_open in function list. For security reasons services like Gmail using Temp App Passwords, create it here: https://myaccount.google.com/u/1/apppasswords
Then configure /common/config/main.php
-> mailer
component, just write full email (myname@gmail.com) and app password
Email design
All email templates placed at /common/mails/
, Welcome
template will sent after signup and verification by default (for signup via socials verification not needed)
Files upload
Created with automatic upload. It save files into storage with path and save field in DB with all path with ;
delimiter. Removes old files, if needed - after replace with new files, after problems with save to DB and after delete row.
Request from client needed (edit or create):
"myFilesField": [
{
"name": "trollface.jpg",
"data": "base64 encoded image"
},
{
"name": "file.zip",
"data": "base64 encoded file"
},
]
You need rules image
or file
validator like this rules section:
[['avatar'], 'image', 'extensions' => ['png', 'gif', 'jpg', ], 'maxSize' => 1024*1024, 'maxFiles' => 1]
UploadBehavior
- enabled by default for each model, it finds fields in rules
with image
or file
validators. Each field in the validator - use for automatic uploads and saves to DB.
You can type your own folder for each field in fieldsFolders
parameter like this:
[
'class' => UploadBehavior::class,
'fieldsFolders' => [
'avatar' => '/usersdata/avatar/',
'uploads' => '/usersdata/uploads/'
]
]
Versioning
You can add versions in GlobalRestConfig
, Rest Generator create pure controller for each version. Existing controllers will not be overwritten.
Nginx settings
You need to add /usersdata/
location to config under same uri yourdomain/usersdata
. It contains users uploads, uploaded and default avatars.
Push notifications
Apple
- Go to Apple Developer Center -> Certificates, Identifiers & Profiles -> Certificates -> + -> Apple Push Notification service SSL (Sandbox & Production)
- Create CSR-key
openssl req -new -newkey rsa:2048 -nodes -keyout yourname.key -out yourname.csr
- Upload to apple, download
.cer
certificate - Make PEM file
openssl x509 -in your_certificate.cer -inform der -out your_certificate.pem
Google (Android)
- Go to Firebase https://console.firebase.google.com/ and create a project
- Project Overview -> Project settings -> Cloud Messaging
- Project credentials -> Server key
FAQ
Why cookies-based sessions and not JWT-token?
Security reasons:
- If SPA-app store token on localstorage - it`s definitely unsafe
- If we set JWT-token into Cookies with SameSite HttpOnly, a leak of JWT secret-key let fake any request for any user. There is additional check needed: a fact that token was sended.
So, no difference between token and session: in any way we need to check it via db.
Anyway, JWT-auth included in the template and you can use it