-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* develop: (28 commits) specify next release add documentation to decorate the env and os add Optional middleware documentation mention it ships with middlewares typo add documentation move where Environment is built for test uniformity remove internal flag as it can be called in users tests fix readme header fix calling configure methods declare app configuration as mutation free mention user facing classes/interfaces flag Application::run as internal add shortcut to use a service as a route handler allow to handle the 404 response allow to map request handlers add router add http application fix class name use innmind/di 2 ...
- Loading branch information
Showing
31 changed files
with
3,185 additions
and
4 deletions.
There are no files selected for viewing
This file contains 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 |
---|---|---|
@@ -1,3 +1,14 @@ | ||
# Changelog | ||
|
||
## [Unreleased] | ||
## 1.0.0 - 2023-01-01 | ||
|
||
### Added | ||
|
||
- `Innmind\Framework\Application` | ||
- `Innmind\Framework\Main\Cli` | ||
- `Innmind\Framework\Main\Http` | ||
- `Innmind\Framework\Middleware` | ||
- `Innmind\Framework\Middleware\Optional` | ||
- `Innmind\Framework\Middleware\LoadDotEnv` | ||
- `Innmind\Framework\Environment` | ||
- `Innmind\Framework\Http\RequestHandler` |
This file contains 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 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 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,15 @@ | ||
# Framework | ||
|
||
The philosophy behind this framework is to have a minimalist foundation to be able to build simple apps but can also accomodate for more complex applications through composition (of the configuration, commands, request handlers and more). | ||
|
||
Another important design is to expose to you the input to handle and an abstraction of the operating system it runs on so you only need to focus on WHAT your app needs to do and NOT HOW. | ||
|
||
These topics will guide you through the simplest cases to more complex ones: | ||
- [Build an HTTP app](http.md) | ||
- [Build a CLI app](cli.md) | ||
- [Services](services.md) | ||
- [Middlewares](middlewares.md) | ||
- [Build an app that runs through HTTP and CLI](http-and-cli.md) | ||
- [Testing](testing.md) | ||
- [Add variables to the environment](environment.md) | ||
- [Decorate the operating system](operating-system.md) |
This file contains 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,158 @@ | ||
# Build a CLI app | ||
|
||
The first of any CLI app is to create an `entrypoint.php` that you'll call with the `php` command. | ||
|
||
```php | ||
<?php | ||
declare(strict_types = 1); | ||
|
||
require 'path/to/composer/autoload.php'; | ||
|
||
use Innmind\Framework\{ | ||
Main\Cli, | ||
Application, | ||
}; | ||
|
||
new class extends Cli { | ||
protected function configure(Application $app): Application | ||
{ | ||
return $app; | ||
} | ||
}; | ||
``` | ||
|
||
By default this application will write `Hello world` when you call `php entrypoint.php`. | ||
|
||
## Handle commands | ||
|
||
This example reuses the AMQP clients defined in the [services topic](services.md). | ||
|
||
```php | ||
use Innmind\Framework\{ | ||
Main\Cli, | ||
Application, | ||
}; | ||
use Innmind\CLI\{ | ||
Console, | ||
Command, | ||
}; | ||
use Innmind\DI\Container; | ||
use Innmind\AMQP\{ | ||
Client, | ||
Command\Publish, | ||
Command\Get, | ||
Model\Basic\Message, | ||
}; | ||
use Innmind\Immutable\Str; | ||
|
||
new class extends Cli { | ||
protected function configure(Application $app): Application | ||
{ | ||
return $app | ||
->service('producer-client', /* see services topic */) | ||
->service('consumer-client', /* see services topic */) | ||
->command(static fn(Container $container) => new class($container('producer-client')) implements Command { | ||
public function __construct( | ||
private Client $amqp, | ||
) { | ||
} | ||
|
||
public function __invoke(Console $console): Console | ||
{ | ||
$message = Message::of(Str::of( | ||
$console->arguments()->get('url'), | ||
)); | ||
|
||
return $this | ||
->client | ||
->with(Publish::one($message)->to('some-exchange')) | ||
->run($console) | ||
->match( | ||
static fn($console) => $console->output(Str::of("Message published\n")), | ||
static fn() => $console->error(Str::of("Something went wrong\n")), | ||
); | ||
} | ||
|
||
public function usage(): string | ||
{ | ||
return 'publish url'; | ||
} | ||
}) | ||
->command(static fn(Container $container) => new class($container('consumer-client')) implements Command { | ||
public function __construct( | ||
private Client $amqp, | ||
) { | ||
} | ||
|
||
public function __invoke(Console $console): Console | ||
{ | ||
return $this | ||
->client | ||
->with(Get::of('some-queue')) | ||
->run($console) | ||
->match( | ||
static fn($console) => $console->output(Str::of("One message pulled from queue\n")), | ||
static fn() => $console->error(Str::of("Something went wrong\n")), | ||
); | ||
} | ||
|
||
public function usage(): string | ||
{ | ||
return 'consume'; | ||
} | ||
}); | ||
} | ||
}; | ||
``` | ||
|
||
This example creates 2 commands `publish` (that expect one argument) and `consume`. Each command relies on a service to access the AMQP client. | ||
|
||
You can call `php entrypoint.php publish https://github.com` that will call the first command and `php entrypoint.php consume` will call the second one. | ||
|
||
## Execute code on any command | ||
|
||
Sometimes you want to execute some code on every command. So far your only approach would be to use inheritance on each `Command` but this leads to bloated code. | ||
|
||
Fortunately there is better approach: composition of `Command`s. | ||
|
||
```php | ||
use Innmind\Framework\{ | ||
Main\Cli, | ||
Application, | ||
}; | ||
use Innmind\CLI\{ | ||
Console, | ||
Command, | ||
}; | ||
|
||
new class extends Cli { | ||
protected function configure(Application $app): Application | ||
{ | ||
return $app | ||
->mapCommand( | ||
static fn(Command $command) => new class($command) implements Command { | ||
public function __construct( | ||
private Command $inner, | ||
) { | ||
} | ||
|
||
public function __invoke(Console $console): Console | ||
{ | ||
// do something before the real command | ||
|
||
return ($this->inner)($console); | ||
} | ||
|
||
public function usage(): string | ||
{ | ||
return $this->inner->usage(); | ||
} | ||
} | ||
) | ||
->service(/* ... */) | ||
->service(/* ... */) | ||
->command(/* ... */) | ||
->command(/* ... */); | ||
} | ||
}; | ||
``` |
Oops, something went wrong.