Skip to content

rawebone/Micro

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Micro

Build Status

Micro is a web framework designed for professionals needing to quick build small, reliable applications. Its goals are to:

  • Be small enough so that it doesn't get in your way or force major architectural decisions about your application (i.e. the framework is not bigger than the picture)
  • Provide the ability to fully test and profile the application layer with ease
  • Provide the ability to debug the request process to see exactly why an error is occurring

Usage

The basic usage of the application is:

<?php require_once "vendor/autoload.php"; $app = new \Micro\Application(); $app->attach(\My\Controllers\Controller()); $app->run(); // Runs the application $app->send(); // Sends the result back to the browser

The attached Controller must implement the Micro\ControllerInterface; the recommended approach to building controllers is via extension of the Micro\DefaultController class:

<?php namespace My\Controllers; use Micro\Request; use Micro\Responder; use Micro\DefaultController; class Controller extends DefaultController { protected function configure() { $this->setUri("/hello/{name}") ->addMethod("GET") ->addCondition("name", "\w+"); } public function accepts(Request $req) { // You can optionally override this method if you want to check any // details about the request; this can help filter out an invalid // request outside of handling it directly, like: return !$req->isAjax(); } public function handle(Request $req, Responder $resp) { return $resp->standard("Hello, {$req->get("name")}"); } }

Testing

Micro contains a base test case for use in conjunction with PHPUnit that allows you to run requests in your tests; you can do this by:

<?php namespace My\Tests\Functional; // You may want to create a custom case for your project. // If using PHP>=5.4 you can use the trait Micro\Testing\ComposableTestCase. use Micro\Testing\AbstractTestCase; class MyControllerTest extends AbstractTestCase { protected static $app; protected function getApplication() { if (!self::$app) { self::$app = require_once "/path/to/app_bootstrap.php"; } return self::$app; } public function testRequest() { $resp = $this->getBrowser()->get("/hello/barry"); $this->assertEquals(200, $resp->getStatusCode()); $this->assertEquals("Hello, barry", $resp->getContent()); } }

Micro ships with a concept called Browsers. These are classes which mimic requests made against your application and return the results which allows you to test your product in a simple, automated fashion. There are three browsers:

Standard Browser

The standard Browser is the root of the browser stack, and can be used to make basic requests against your application.

Tracing Browser

Micro has the ability to trace requests as they progress through the application; this exists to help you get to the route of a problem quickly. After every request made by this browser, a Micro\Testing\TraceResult will be available by calling $browser->lastTrace(). This can be printed straight to output or interrogated.

Profiling Browser

This provides the ability to profile a request for execution time and memory usage- this is, primarily, for use to help measure and improve the performance of the framework but can be useful to end users as well. It is important to note that the execution time/memory usage of the controllers is not the only data captured.

Tracing Your Controller Behaviour

As explained in the Tracing Browser section, requests can be traced through the system and this functionality is optionally available to controllers.

By implementing the Micro\TraceableInterface, you can receive a PSR-3 logger to capture any debug information:

namespace My\Controllers; use Micro\Request; use Micro\Responder; use Micro\DefaultController; use Micro\TraceableInterface; use Psr\Log\LoggerInterface; class Controller extends DefaultController implements TraceableInterface { protected $tracer; // ... public function tracer(LoggerInterface $log) { $this->tracer = $log; } public function handle(Request $req, Responder $resp) { $this->tracer->critical("Help!"); } }

General Approach

Micro, as I hope you will have seen from the above, is designed to be as simple and testable as possible however, in the case you need to change frameworks later on down the line, the suggestion is that the Controllers do the least amount of work possible. For example:

namespace My\Controllers; // ... class Controller extends DefaultController { public function handle(Request $req, Responder $resp) { if ($this->myApplication()->doWork($settingA, $settingB)) { // Handle success } else { // Handle error } } }

Is preferrable to:

namespace My\Controllers; // ... class Controller extends DefaultController { public function handle(Request $req, Responder $resp) { if ($this->doWork($settingA, $settingB)) { // Handle success } else { // Handle error } } protected function doWork($a, $b) { // Complicated API process } }

For two reasons:

  1. This allows you to separate out your business logic from your web logic; the two can then change independently
  2. You are then only testing for correctness of input/output from the web, and not the overall function of your application

This has the additional payoff of allowing you to change systems down the line without major rewrites.

License

MIT License, go hog wild.

About

A small, get-the-job-done web framework with an emphasis on testability

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages