Skip to content

Commit f75d7a6

Browse files
Project base
1 parent 1679679 commit f75d7a6

File tree

84 files changed

+4349
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+4349
-2
lines changed

README.md

+74-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,74 @@
1-
# api
2-
Instructions for creating an API based on zend-expppresive, doctrine, and api-skelton
1+
# DotKernel API
2+
DotKernel's PSR-15 API built around the Zend Expressive API skeleton.
3+
4+
5+
## Getting Started
6+
```bash
7+
$ composer install
8+
```
9+
10+
Next:
11+
* create a new MySQL database, then import in it the following files: `data/schema.sql` and `data/data.sql`
12+
* duplicate `config/autoload/local.php.dist` as `config/autoload/local.php`
13+
* fill in database connection details in `config/autoload/local.php` in the already existing `$database` array
14+
15+
After the project has been successfully installed, make sure you create a new OAuth2 client and generate it's own secret.
16+
17+
18+
## Using the CLI interface:
19+
A complete list of the commands available in Zend Expressive can be accessed by issuing the following command:
20+
```bash
21+
$ composer expressive
22+
```
23+
A complete list of the commands available via Doctrine's CLI can be accessed by issuing the following command:
24+
```bash
25+
$ php vendor/doctrine/orm/bin/doctrine
26+
```
27+
28+
29+
## Creating a module
30+
```bash
31+
$ composer expressive module:create Module
32+
```
33+
This will create the directory structure under: `src/Module` with the module's ConfigProvider and add the it to `config/config.php`
34+
35+
36+
## Creating a request handler
37+
```bash
38+
$ composer expressive handler:create Module\Example\Handler\ExampleHandler
39+
```
40+
This will create:
41+
* the handler: `src/Module/Example/Handler/ExampleHandler.php`
42+
* the factory: `src/Module/Example/Handler/ExampleHandlerFactory.php`
43+
and register it in: `config/autoload/zend-expressive-tooling-factories.global.php`
44+
For a cleaner structure, it is recommended refactoring handler factories by moving them to their own directory: `Factory`. In this case, make sure the factory's namespace is changed accordingly and that the change is reflected in `config/autoload/zend-expressive-tooling-factories.global.php` as well.
45+
46+
47+
## Creating an endpoint
48+
Routes can be created in one of the following locations:
49+
* `config/routes.php`
50+
* `src/{module-name}/RoutesDelegator.php` (First, make sure you registered it in `src/App/ConfigProvider.php`'s `getDependencies` method, under the `delegators` key). By using this method, if you want to move a module between projects, you will automatically move the related endpoints as well.
51+
52+
53+
## Working with entities
54+
A good practice is storing all related entities in the same directory `Entity`, next to the module's `Handler` directory. For example:
55+
* `src/Module/Example/Entity/ExampleEntity.php`
56+
* `src/Module/Example/Entity/ExampleDetailEntity.php`
57+
* `src/Module/Example/Entity/ExampleCategoryEntity.php`
58+
59+
60+
## Running the application
61+
```bash
62+
$ php -S 0.0.0.0:8080 -t public
63+
```
64+
To test the application, visit the [test page](http://localhost:8080/test). You should get the following message:
65+
```json
66+
{
67+
"message": "Welcome to DotKernel API!"
68+
}
69+
```
70+
If the request is successful, you can delete this endpoint from `src/App/RoutesDelegator.php`
71+
72+
73+
## Documentation
74+
Visit [this link](http://localhost:8080/documentation) to access the application's documentation.

Vagrantfile

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Vagrant configuration for zend-expressive workshop
2+
# @author Enrico Zimuel ([email protected])
3+
4+
VAGRANTFILE_API_VERSION = '2'
5+
6+
$script = <<SCRIPT
7+
# Fix for Temporary failure resolving 'archive.ubuntu.com'
8+
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf > /dev/null
9+
10+
# Install dependencies
11+
apt-get update
12+
apt-get install -y nginx git curl sqlite3 php7.2 php7.2-cli php7.2-fpm php7.2-sqlite3 php7.2-pdo php7.2-xml php7.2-zip php7.2-mbstring
13+
14+
# Configure Nginx
15+
echo "server {
16+
listen 8080;
17+
18+
root /home/ubuntu/zend-expressive-api/public;
19+
server_name ubuntu-xenial;
20+
21+
# Logs
22+
access_log /home/ubuntu/zend-expressive-api/log/access_log;
23+
error_log /home/ubuntu/zend-expressive-api/log/error_log;
24+
25+
index index.php index.html index.htm;
26+
27+
location / {
28+
try_files \\$uri \\$uri/ /index.php;
29+
}
30+
location ~ \\.php\$ {
31+
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
32+
include snippets/fastcgi-php.conf;
33+
}
34+
# Block access to .htaccess
35+
location ~ \\.htaccess {
36+
deny all;
37+
}
38+
}" > /etc/nginx/sites-available/zend-expressive-api
39+
chmod 644 /etc/nginx/sites-available/zend-expressive-api
40+
ln -s /etc/nginx/sites-available/zend-expressive-api /etc/nginx/sites-enabled/zend-expressive-api
41+
service nginx restart
42+
43+
if [ -e /usr/local/bin/composer ]; then
44+
/usr/local/bin/composer self-update
45+
else
46+
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
47+
fi
48+
49+
chmod +r /home/ubuntu/zend-expressive-api/data/oauth2/*
50+
SCRIPT
51+
52+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
53+
config.vm.box = 'bento/ubuntu-18.04'
54+
config.vm.network "forwarded_port", guest: 8080, host: 8080
55+
config.vm.synced_folder ".", "/home/ubuntu/zend-expressive-api", id: "vagrant-root",
56+
owner: "vagrant",
57+
group: "www-data",
58+
mount_options: ["dmode=775,fmode=660"]
59+
config.vm.provision 'shell', inline: $script
60+
61+
config.vm.provider "virtualbox" do |vb|
62+
vb.customize ["modifyvm", :id, "--memory", "1024"]
63+
vb.customize ["modifyvm", :id, "--name", "zend-expressive-api"]
64+
end
65+
end

bin/clear-config-cache.php

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* Script for clearing the configuration cache.
4+
*
5+
* Can also be invoked as `composer clear-config-cache`.
6+
*
7+
* @see https://github.com/zendframework/zend-expressive-skeleton for the canonical source repository
8+
* @copyright Copyright (c) 2017 Zend Technologies USA Inc. (http://www.zend.com)
9+
* @license https://github.com/zendframework/zend-expressive-skeleton/blob/master/LICENSE.md New BSD License
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
chdir(__DIR__ . '/../');
15+
16+
require 'vendor/autoload.php';
17+
18+
$config = include 'config/config.php';
19+
20+
if (! isset($config['config_cache_path'])) {
21+
echo "No configuration cache path found" . PHP_EOL;
22+
exit(0);
23+
}
24+
25+
if (! file_exists($config['config_cache_path'])) {
26+
printf(
27+
"Configured config cache file '%s' not found%s",
28+
$config['config_cache_path'],
29+
PHP_EOL
30+
);
31+
exit(0);
32+
}
33+
34+
if (false === unlink($config['config_cache_path'])) {
35+
printf(
36+
"Error removing config cache file '%s'%s",
37+
$config['config_cache_path'],
38+
PHP_EOL
39+
);
40+
exit(1);
41+
}
42+
43+
printf(
44+
"Removed configured config cache file '%s'%s",
45+
$config['config_cache_path'],
46+
PHP_EOL
47+
);
48+
exit(0);

composer.json

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
{
2+
"name": "dotkernel/api",
3+
"description": "DotKernel API",
4+
"type": "project",
5+
"homepage": "https://github.com/dotkernel/api",
6+
"license": "MIT",
7+
"authors": [
8+
{
9+
"name": "DotKernel Team",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"keywords": [
14+
"skeleton",
15+
"middleware",
16+
"psr",
17+
"psr-7",
18+
"psr-11",
19+
"psr-15",
20+
"zf",
21+
"zendframework",
22+
"zend-expressive"
23+
],
24+
"config": {
25+
"sort-packages": true
26+
},
27+
"extra": {
28+
"zf": {
29+
"component-whitelist": [
30+
"zendframework/zend-expressive",
31+
"zendframework/zend-expressive-helpers",
32+
"zendframework/zend-expressive-router",
33+
"zendframework/zend-httphandlerrunner",
34+
"zendframework/zend-expressive-fastroute"
35+
]
36+
}
37+
},
38+
"support": {
39+
"issues": "https://github.com/zendframework/zend-expressive-skeleton/issues",
40+
"source": "https://github.com/zendframework/zend-expressive-skeleton",
41+
"rss": "https://github.com/zendframework/zend-expressive-skeleton/releases.atom",
42+
"slack": "https://zendframework-slack.herokuapp.com",
43+
"forum": "https://discourse.zendframework.com/c/questions/expressive"
44+
},
45+
"require": {
46+
"php": "^7.2",
47+
"dasprid/container-interop-doctrine": "^1.1",
48+
"dotkernel/dot-errorhandler": "^1.0",
49+
"moontoast/math": "^1.1",
50+
"ramsey/uuid-doctrine": "^1.5",
51+
"roave/security-advisories": "dev-master",
52+
"swagger-api/swagger-ui": "^3.22",
53+
"tuupola/cors-middleware": "^0.9.4",
54+
"zendframework/zend-component-installer": "^2.1.1",
55+
"zendframework/zend-config-aggregator": "^1.0",
56+
"zendframework/zend-db": "^2.9.3",
57+
"zendframework/zend-diactoros": "^1.7.1",
58+
"zendframework/zend-expressive": "^3.0.1",
59+
"zendframework/zend-expressive-authentication": "^1.0",
60+
"zendframework/zend-expressive-authentication-oauth2": "^1.0",
61+
"zendframework/zend-expressive-authorization-acl": "^1.0",
62+
"zendframework/zend-expressive-authorization-rbac": "^1.0",
63+
"zendframework/zend-expressive-fastroute": "^3.0",
64+
"zendframework/zend-expressive-hal": "^1.0.2",
65+
"zendframework/zend-expressive-helpers": "^5.0",
66+
"zendframework/zend-hydrator": "^2.2",
67+
"zendframework/zend-inputfilter": "^2.8.1",
68+
"zendframework/zend-paginator": "^2.8.1",
69+
"zendframework/zend-problem-details": "^1.0",
70+
"zendframework/zend-psr7bridge": "^1.2",
71+
"zendframework/zend-servicemanager": "^3.3",
72+
"zendframework/zend-stdlib": "^3.1"
73+
},
74+
"require-dev": {
75+
"phpunit/phpunit": "^7.0.1",
76+
"zendframework/zend-coding-standard": "~1.0.0",
77+
"zendframework/zend-expressive-tooling": "^1.0",
78+
"zfcampus/zf-development-mode": "^3.1"
79+
},
80+
"autoload": {
81+
"psr-4": {
82+
"App\\": "src/App/"
83+
}
84+
},
85+
"autoload-dev": {
86+
"psr-4": {
87+
"AppTest\\": "test/AppTest/"
88+
}
89+
},
90+
"scripts": {
91+
"post-create-project-cmd": [
92+
"@development-enable"
93+
],
94+
"development-disable": "zf-development-mode disable",
95+
"development-enable": "zf-development-mode enable",
96+
"development-status": "zf-development-mode status",
97+
"expressive": "expressive --ansi",
98+
"check": [
99+
"@cs-check",
100+
"@test",
101+
"@analyze"
102+
],
103+
"analyze": "phpstan analyze -l max -c ./phpstan.installer.neon ./src ./config",
104+
"clear-config-cache": "php bin/clear-config-cache.php",
105+
"cs-check": "phpcs",
106+
"cs-fix": "phpcbf",
107+
"serve": "php -S 0.0.0.0:8080 -t public/",
108+
"test": "phpunit --colors=always",
109+
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml"
110+
}
111+
}

config/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
development.config.php

config/autoload/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
local.php
2+
*.local.php
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
return [
6+
'zend-expressive-authorization-acl' => [
7+
'roles' => [
8+
'admin' => [],
9+
'member' => ['admin'],
10+
'guest' => ['member'],
11+
],
12+
'resources' => [
13+
'user',
14+
'users',
15+
'avatar',
16+
],
17+
'allow' => [
18+
'admin' => ['*'],
19+
'member' => ['*'],
20+
'guest' => []
21+
]
22+
],
23+
'zend-expressive-authorization-rbac' => [
24+
'roles' => [
25+
'admin' => [],
26+
'member' => ['admin'],
27+
'guest' => ['member'],
28+
],
29+
'permissions' => [
30+
'member' => [
31+
'avatar',
32+
'users',
33+
'user',
34+
],
35+
],
36+
]
37+
];
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Zend\Expressive as Expressive;
6+
7+
return [
8+
// Provides application-wide services.
9+
// We recommend using fully-qualified class names whenever possible as
10+
// service names.
11+
'dependencies' => [
12+
// Use 'aliases' to alias a service name to another service. The
13+
// key is the alias name, the value is the service to which it points.
14+
'aliases' => [
15+
Dot\ErrorHandler\ErrorHandlerInterface::class => Dot\ErrorHandler\LogErrorHandler::class,
16+
League\OAuth2\Server\Repositories\UserRepositoryInterface::class => App\Common\OauthUserRepository::class,
17+
Expressive\Authentication\UserInterface::class => App\User\Entity\UserIdentity::class,
18+
Expressive\Authorization\AuthorizationInterface::class => Expressive\Authorization\Rbac\ZendRbac::class
19+
],
20+
// Use 'invokables' for constructor-less services, or services that do
21+
// not require arguments to the constructor. Map a service name to the
22+
// class name.
23+
'invokables' => [
24+
// Fully\Qualified\InterfaceName::class => Fully\Qualified\ClassName::class,
25+
],
26+
// Use 'factories' for services provided by callbacks/factory classes.
27+
'factories' => [
28+
App\Common\OauthUserRepository::class => App\Common\OauthUserRepositoryFactory::class,
29+
App\User\Entity\UserIdentity::class => App\User\Factory\UserIdentityFactory::class,
30+
Tuupola\Middleware\CorsMiddleware::class => App\Cors\Factory\CorsFactory::class
31+
],
32+
],
33+
];
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
/**
3+
* Development-only configuration.
4+
*
5+
* Put settings you want enabled when under development mode in this file, and
6+
* check it into your repository.
7+
*
8+
* Developers on your team will then automatically enable them by calling on
9+
* `composer development-enable`.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
return [
15+
];

0 commit comments

Comments
 (0)