-
Notifications
You must be signed in to change notification settings - Fork 35
Framework V2 #102
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
Merged
Framework V2 #102
Changes from all commits
Commits
Show all changes
90 commits
Select commit
Hold shift + click to select a range
e817592
adapters and refactor request and response
lohanidamodar ee75d8a
Merge remote-tracking branch 'origin/feat-routing-v2' into feat-v2
lohanidamodar 02006b2
update test and fix
lohanidamodar 151434c
fix lint
lohanidamodar af83713
fix tests
lohanidamodar 4260458
fixes
lohanidamodar 4355dfa
fix param reference
lohanidamodar 29909da
downgrade symfony console
lohanidamodar 63121c8
downgrade phpbench
lohanidamodar b6d83d5
remove leftover code
lohanidamodar 9fbb075
move namespace
lohanidamodar f23bbe8
fix formatting
lohanidamodar 45beee6
update constructor
lohanidamodar d8350d1
Update src/Adapter/Swoole/Server.php
lohanidamodar 415a236
Merge branch 'feat-v2' of https://github.com/utopia-php/framework int…
lohanidamodar 146ae35
fix test
lohanidamodar 4eeddf7
update readme
lohanidamodar 803dddc
file loading support in servers
lohanidamodar 1876af8
fix and update test for both server adapters
lohanidamodar cbe0901
fix test flow
lohanidamodar c2e70ab
fix parameter name
lohanidamodar 136c318
Update src/Adapter.php
lohanidamodar a3bdb49
Update src/Adapter.php
lohanidamodar ab04d15
update dockerfile name
lohanidamodar 8b448f6
update readme
lohanidamodar eaf63bd
abstract away app start
lohanidamodar bd9ff87
rename dockerfile
lohanidamodar c8de4cc
rename App -> Http
lohanidamodar 644687b
fix formatting
lohanidamodar 4bcf458
update namespace
lohanidamodar 31bd350
static file handling
lohanidamodar 97f9320
fix formatting
lohanidamodar dc96765
upate php version for test - dev dependencies now require 8.1
lohanidamodar 73d8f0b
more server related callbacks
lohanidamodar a912fab
start hook
lohanidamodar ab4544a
worker start hooks
lohanidamodar db4ae13
fix setting resource
lohanidamodar 4eb0583
fix reset
lohanidamodar 5a6d171
swoole beforeShutdown callback
lohanidamodar 22bd6d6
support request hooks
lohanidamodar f5a483a
add getter for swoole internal request
lohanidamodar 0e67327
getter for swoole response
lohanidamodar c2cc0f2
Merge remote-tracking branch 'origin/feat-routing-v2' into feat-v2
lohanidamodar 552bccd
get fresh resource each time by default
lohanidamodar 50d4cd5
enable context
lohanidamodar c0b5d73
fresh is now false by default
lohanidamodar 33698fc
fix resource for context null
lohanidamodar cd3c30a
unused code
lohanidamodar 0e4281d
add swoole test
lohanidamodar 0f69480
update tests
lohanidamodar 6dcef9a
fix test with resource reset
lohanidamodar 242a20f
fix lint
lohanidamodar be16910
Merge remote-tracking branch 'origin' into feat-v2
lohanidamodar 54074b9
set a default context and make context string
lohanidamodar 11488b1
make utopia default context
lohanidamodar d2909e7
upgrade callback
lohanidamodar 52c1a06
fix callback reset type
lohanidamodar 7466616
Merge branch 'master' of https://github.com/utopia-php/framework into…
lohanidamodar b7ff4de
fix check and lint
lohanidamodar 1105527
fixes after merge
lohanidamodar f3cb041
update missing resource
lohanidamodar daba6a7
Merge remote-tracking branch 'origin/master' into feat-v2
lohanidamodar d714fcb
remove view from framework
lohanidamodar 6c8ffb0
Fix Swoole coroutine http server
Meldiron a4916b4
Disable forced type on onRequest
Meldiron 69b83a3
Add route resource
Meldiron 2213a3c
Fix tests
Meldiron 96e1f58
Tests fix
Meldiron c9ea90e
Add swoole resources
Meldiron e34ed9c
Add default context to getResources
Meldiron c68f74e
Fix memory leak
Meldiron a73f0a0
Linter fix
Meldiron 7405c1f
Improve Assoc validator with length param
Meldiron 55792e0
Add multiple validator
vermakhushboo d81dd2a
Merge pull request #109 from utopia-php/fix-v2-swoole-coroutines
Meldiron 399c89e
Merge remote-tracking branch 'origin/master' into feat-v2
Meldiron dff85bd
CI/CD fixes
Meldiron e44076b
Update README
Meldiron 8dfe731
Auto-add context to swoole
Meldiron 6cd3232
Update swoole README
Meldiron ceae30f
Improve readme, add example
Meldiron 3ba0cd1
Grammar fixes
Meldiron ecf9791
Update README.md
Meldiron 569428c
Update README.md
Meldiron f5e2ac0
Add fpm resources
Meldiron 8ef5482
Fix formatting
Meldiron 23dedb9
Merge pull request #113 from utopia-php/feat-add-multiple-validator-t…
eldadfux d8ef76a
PR review changes
Meldiron d5e2929
Improve swoole constructor
Meldiron ee4fc6d
Remove worker concept
Meldiron File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| FROM composer:2.0 AS step0 | ||
|
|
||
|
|
||
| ARG TESTING=true | ||
|
|
||
| ENV TESTING=$TESTING | ||
|
|
||
| WORKDIR /usr/local/src/ | ||
|
|
||
| COPY composer.* /usr/local/src/ | ||
|
|
||
| RUN composer install --ignore-platform-reqs --optimize-autoloader \ | ||
| --no-plugins --no-scripts --prefer-dist \ | ||
| `if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi` | ||
|
|
||
| FROM appwrite/base:0.4.3 as final | ||
| LABEL maintainer="[email protected]" | ||
|
|
||
| WORKDIR /usr/src/code | ||
|
|
||
| COPY ./src /usr/src/code/src | ||
| COPY ./tests /usr/src/code/tests | ||
| COPY ./phpunit.xml /usr/src/code/phpunit.xml | ||
| COPY ./phpbench.json /usr/src/code/phpbench.json | ||
| COPY --from=step0 /usr/local/src/vendor /usr/src/code/vendor | ||
|
|
||
| EXPOSE 80 | ||
|
|
||
| CMD ["php", "tests/e2e/server-swoole.php"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
|
|
||
| Utopia Framework is a PHP MVC based framework with minimal must-have features for professional, simple, advanced and secure web development. This library is maintained by the [Appwrite team](https://appwrite.io). | ||
|
|
||
| Utopia Framework is dependency free. Any extra features such as authentication, caching will be available as standalone models in order to keep the framework core as clean, light and easy to learn. | ||
| Utopia Framework is dependency-free. Any extra features, such as authentication or caching, will be available as standalone models in order to keep the framework core clean, light, and easy to learn. | ||
|
|
||
| ## Getting Started | ||
|
|
||
|
|
@@ -17,19 +17,21 @@ Install using composer: | |
| composer require utopia-php/framework | ||
| ``` | ||
|
|
||
| Init your first application: | ||
| Init your first application in `src/server.php`: | ||
|
|
||
| ```php | ||
| require_once __DIR__ . '/../../vendor/autoload.php'; | ||
| require_once __DIR__.'/../vendor/autoload.php'; | ||
|
|
||
| use Utopia\App; | ||
| use Utopia\Request; | ||
| use Utopia\Response; | ||
| use Utopia\Http\Http; | ||
| use Utopia\Http\Request; | ||
| use Utopia\Http\Response; | ||
| use Utopia\Http\Adapter\FPM\Server; | ||
|
|
||
| App::get('/hello-world') // Define Route | ||
| Http::get('/hello-world') // Define Route | ||
| ->inject('request') | ||
| ->inject('response') | ||
| ->action( | ||
| function($request, $response) { | ||
| function(Request $request, Response $response) { | ||
| $response | ||
| ->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate') | ||
| ->addHeader('Expires', '0') | ||
|
|
@@ -38,90 +40,222 @@ App::get('/hello-world') // Define Route | |
| } | ||
| ); | ||
|
|
||
| App::setMode(App::MODE_TYPE_PRODUCTION); // Define Mode | ||
| Http::setMode(Http::MODE_TYPE_PRODUCTION); | ||
|
|
||
| $http = new Http(new Server(), 'America/New_York'); | ||
| $http->start(); | ||
| ``` | ||
|
|
||
| $app = new App('America/New_York'); | ||
| $request = new Request(); | ||
| $response = new Response(); | ||
| Run HTTP server: | ||
|
|
||
| $app->run($request, $response); | ||
| ```bash | ||
| php -S localhost:8000 src/server2.php | ||
| ``` | ||
|
|
||
| ### Hooks | ||
| Send HTTP request: | ||
|
|
||
| ```bash | ||
| curl http://localhost:8000/hello-world | ||
| ``` | ||
|
|
||
| ### Server Adapters | ||
|
|
||
| The library supports server adapters to be able to run on any PHP setup. For instance, you could use the FPM server or the Swoole server. | ||
|
|
||
| #### Use PHP FPM server | ||
|
|
||
| ```php | ||
| use Utopia\Http\Http; | ||
| use Utopia\Http\Response; | ||
| use Utopia\Http\Adapter\FPM\Server; | ||
|
|
||
| Http::get('/') | ||
| ->inject('response') | ||
| ->action( | ||
| function(Response $response) { | ||
| $response->send('Hello from PHP FPM'); | ||
| } | ||
| ); | ||
|
|
||
| There are three types of hooks, init hooks, shutdown hooks and error hooks. Init hooks are executed before the route action is executed. Shutdown hook is executed after route action is executed before application shuts down. Finally error hooks are executed whenever there's an error in the application lifecycle. You can provide multiple hooks for each stage. If you do not assign groups to the hook, by default the hook will be executed for every route. | ||
| $http = new Http(new Server(), 'America/New_York'); | ||
| $http->start(); | ||
| ``` | ||
|
|
||
| > When using PHP FPM, you can use the command `php -S localhost:80 src/server.php` to run the HTTP server locally | ||
|
|
||
| #### Using Swoole server | ||
|
|
||
| ```php | ||
| require_once __DIR__ . '/../../vendor/autoload.php'; | ||
| use Utopia\Http\Http; | ||
| use Utopia\Http\Request; | ||
| use Utopia\Http\Response; | ||
| use Utopia\Http\Adapter\Swoole\Server; | ||
|
|
||
| Http::get('/') | ||
| ->inject('request') | ||
| ->inject('response') | ||
| ->action( | ||
| function(Request $request, Response $response) { | ||
| $response->send('Hello from Swoole'); | ||
| } | ||
| ); | ||
|
|
||
| $http = new Http(new Server('0.0.0.0', '80'), 'America/New_York'); | ||
| $http->start(); | ||
| ``` | ||
|
|
||
| > When using Swoole, you can use the command `php src/server.php` to run the HTTP server locally, but you need Swoole installed. For setup with Docker, check out our [example application](/example) | ||
|
|
||
| ### Parameters | ||
|
|
||
| Parameters are used to receive input into endpoint action from the HTTP request. Parameters could be defined as URL parameters or in a body with a structure such as JSON. | ||
|
|
||
| Every parameter must have a validator defined. Validators are simple classes that verify the input and ensure the security of inputs. You can define your own validators or use some of [built-in validators](/src/Http/Validator). | ||
|
|
||
| Define an endpoint with params: | ||
|
|
||
| ```php | ||
| Http::get('/') | ||
| ->param('name', 'World', new Text(256), 'Name to greet. Optional, max length 256.', true) | ||
| ->inject('response') | ||
| ->action(function(string $name, Response $response) { | ||
| $response->send('Hello ' . $name); | ||
| }); | ||
| ``` | ||
|
|
||
| Send HTTP requests to ensure the parameter works: | ||
|
|
||
| ```bash | ||
| curl http://localhost:8000/hello-world | ||
| curl http://localhost:8000/hello-world?name=Utopia | ||
| curl http://localhost:8000/hello-world?name=Appwrite | ||
| ``` | ||
|
|
||
| It's always recommended to use params instead of getting params or body directly from the request resource. If you do that intentionally, always make sure to run validation right after fetching such a raw input. | ||
|
|
||
| ### Hooks | ||
|
|
||
| There are three types of hooks: | ||
|
|
||
| use Utopia\App; | ||
| use Utopia\Request; | ||
| use Utopia\Response; | ||
| - **Init hooks** are executed before the route action is executed | ||
| - **Shutdown hooks** are executed after route action is finished, but before application shuts down | ||
| - **Error hooks** are executed whenever there's an error in the application lifecycle. | ||
|
|
||
| App::init() | ||
| You can provide multiple hooks for each stage. If you do not assign groups to the hook, by default, the hook will be executed for every route. If a group is defined on a hook, it will only run during the lifecycle of a request with the same group name on the action. | ||
|
|
||
| ```php | ||
| Http::init() | ||
| ->inject('request') | ||
| ->action(function(Request $request) { | ||
| \var_dump("Recieved: " . $request->getMethod() . ' ' . $request->getURI()); | ||
| }); | ||
|
|
||
| Http::shutdown() | ||
| ->inject('response') | ||
| ->action(function($response) { | ||
| $response->addHeader('content-type', 'application/json'); | ||
| ->action(function(Response $response) { | ||
| \var_dump('Responding with status code: ' . $response->getStatusCode()); | ||
| }); | ||
|
|
||
| App::error() | ||
| Http::error() | ||
| ->inject('error') | ||
| ->inject('response') | ||
| ->action(function($error, $response) { | ||
| ->action(function(\Throwable $error, Response $response) { | ||
| $response | ||
| ->setStatusCode(500) | ||
| ->send('Error occurred ' . $error); | ||
| }); | ||
| ``` | ||
|
|
||
| App::get('/hello-world') // Define Route | ||
| ->inject('request') | ||
| Hooks are designed to be actions that run during the lifecycle of requests. Hooks should include functional logic. Hooks are not designed to prepare dependencies or context for the request. For such a use case, you should use resources. | ||
|
|
||
| ### Groups | ||
|
|
||
| Groups allow you to define common behavior for multiple endpoints. | ||
|
|
||
| You can start by defining a group on an endpoint. Keep in mind you can also define multiple groups on a single endpoint. | ||
|
|
||
| ```php | ||
| Http::get('/v1/health') | ||
| ->groups(['api', 'public']) | ||
| ->inject('response') | ||
| ->action( | ||
| function($request, $response) { | ||
| $response | ||
| ->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate') | ||
| ->addHeader('Expires', '0') | ||
| ->addHeader('Pragma', 'no-cache') | ||
| ->json(['Hello' => 'World']); | ||
| function(Response $response) { | ||
| $response->send('OK'); | ||
| } | ||
| ); | ||
| ``` | ||
|
|
||
| App::setMode(App::MODE_TYPE_PRODUCTION); // Define Mode | ||
| Now you can define hooks that would apply only to specific groups. Remember, hooks can also be assigned to multiple groups. | ||
|
|
||
| $app = new App('America/New_York'); | ||
eldadfux marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| $request = new Request(); | ||
| $response = new Response(); | ||
| ```php | ||
| Http::init() | ||
| ->groups(['api']) | ||
| ->inject('request') | ||
| ->inject('response') | ||
| ->action(function(Request $request, Response $response) { | ||
| $apiKey = $request->getHeader('x-api-key', ''); | ||
|
|
||
| $app->run($request, $response); | ||
| if(empty($apiKey)) { | ||
| $response | ||
| ->setStatusCode(Response::STATUS_CODE_UNAUTHORIZED) | ||
| ->send('API key missing.'); | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| Groups are designed to be actions that run during the lifecycle of requests to endpoints that have some logic in common. Groups allow you to prevent code duplication and are designed to be defined anywhere in your source code to allow flexibility. | ||
|
|
||
| ### Resources | ||
|
|
||
| Resources allow you to prepare dependencies for requests such as database connection or the user who sent the request. A new instance of a resource is created for every request. | ||
|
|
||
| Define a resource: | ||
|
|
||
| ```php | ||
| Http::setResource('timing', function() { | ||
| return \microtime(true); | ||
| }); | ||
| ``` | ||
|
|
||
| Inject resource into endpoint action: | ||
|
|
||
| ```php | ||
| Http::get('/') | ||
| ->inject('timing') | ||
| ->inject('response') | ||
| ->action(function(float $timing, Response $response) { | ||
| $response->send('Request Unix timestamp: ' . \strval($timing)); | ||
| }); | ||
| ``` | ||
|
|
||
| Inject resource into a hook: | ||
|
|
||
| ```php | ||
| Http::shutdown() | ||
| ->inject('timing') | ||
| ->action(function(float $timing) { | ||
| $difference = \microtime(true) - $timing; | ||
| \var_dump("Request took: " . $difference . " seconds"); | ||
| }); | ||
| ``` | ||
|
|
||
| In advanced scenarios, resources can also be injected into other resources or endpoint parameters. | ||
|
|
||
| Resources are designed to prepare dependencies or context for the request. Resources are not meant to do functional logic or return callbacks. For such a use case, you should use hooks. | ||
|
|
||
| To learn more about Framework architecture and features, check out more in-depth [Getting started guide](/docs/Getting-Starting-Guide.md). | ||
|
|
||
| ## System Requirements | ||
|
|
||
| Utopia Framework requires PHP 8.0 or later. We recommend using the latest PHP version whenever possible. | ||
|
|
||
| ## More from Utopia | ||
|
|
||
| Our ecosystem support other thin PHP projects aiming to extend the core PHP Utopia framework. | ||
| Our ecosystem supports other thin PHP projects aiming to extend the core PHP Utopia framework. | ||
|
|
||
| Each project is focused on solving a single, very simple problem and you can use composer to include any of them in your next project. | ||
|
|
||
| Library | Description | ||
| --- | --- | ||
| **[Utopia AB](https://github.com/utopia-php/ab)** | Simple PHP library for managing AB testing on the server side. | ||
| **[Utopia Abuse](https://github.com/utopia-php/abuse)** | Simple PHP library for rate limiting usage of different features in your app or API. | ||
| **[Utopia Analytics](https://github.com/utopia-php/analytics)** | Simple PHP library to send information about events or pageviews to Google Analytics. | ||
| **[Utopia Audit](https://github.com/utopia-php/audit)** | Simple PHP library for audit logging users actions and system events | ||
| **[Utopia Cache](https://github.com/utopia-php/cache)** | Simple PHP library for managing cache with different storage adapters. | ||
| **[Utopia CLI](https://github.com/utopia-php/cli)** | Simple PHP library for for building simple command line tools. | ||
| **[Utopia Config](https://github.com/utopia-php/config)** | Simple PHP library for managing your app configuration. | ||
| **[Utopia Database](https://github.com/utopia-php/database)** | Simple PHP library for managing application persistency. It supports multiple database adapters. | ||
| **[Utopia Domains](https://github.com/utopia-php/domains)** | Simple PHP library for parsing domain names. | ||
| **[Utopia Image](https://github.com/utopia-php/image)** | Simple PHP library for creating common image manipulations that is easy to use. | ||
| **[Utopia Locale](https://github.com/utopia-php/locale)** | Simple PHP library for adding support to multiple locales in your app or API. | ||
| **[Utopia Preloader](https://github.com/utopia-php/preloader)** | Simple PHP library for managing PHP preloading configuration. | ||
| **[Utopia Registry](https://github.com/utopia-php/registry)** | Simple PHP library for dependency injection and lazy loading of objects or resources. | ||
| **[Utopia System](https://github.com/utopia-php/system)** | Simple PHP library for obtaining information about the host's system. | ||
| **[Utopia Storage](https://github.com/utopia-php/storage)** | Simple and lite PHP library for managing application storage. It supports multiple storage adapters. | ||
| You can find all libraries in [GitHub Utopia organization](https://github.com/utopia-php). | ||
|
|
||
| ## Contributing | ||
|
|
||
|
|
@@ -133,12 +267,6 @@ You can refer to the [Contributing Guide](https://github.com/utopia-php/framewor | |
|
|
||
| For security issues, please email [email protected] instead of posting a public issue in GitHub. | ||
|
|
||
| ### Testing | ||
|
|
||
| - `docker-compose up -d` | ||
| - `docker-compose exec web vendor/bin/phpunit --configuration phpunit.xml` | ||
| - `docker-compose exec web vendor/bin/psalm --show-info=true` | ||
|
|
||
| ## Copyright and license | ||
|
|
||
| The MIT License (MIT) [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.