Getting Started =============== This page provides a brief introduction to WellRESTed. We'll take a tour of some of the features of WellRESTed without getting into too much depth. To start, we'll make a "`Hello, world!`_" to demonstrate the concepts of middleware and routing and show how to read variables from the request path. Hello, World! ^^^^^^^^^^^^^ Let's start with a very basic "Hello, world!". Here, we will create a server. A ``WellRESTed\Server`` reads the incoming request from the client, dispatches some middleware_, and transmits a response back to the client. Our middleware is a function that returns a response with the status code set to ``200`` and the body set to "Hello, world!". .. _`Example 1`: .. rubric:: Example 1: Simple "Hello, world!" .. code-block:: php add(function ($request, $response, $next) { // Update the response with the greeting, status, and content-type. $response = $response->withStatus(200) ->withHeader("Content-type", "text/plain") ->withBody(new Stream("Hello, world!")); // Use $next to forward the request on to the next middleware, if any. return $next($request, $response); }); // Read the request sent to the server and use it to output a response. $server->respond(); .. note:: The middleware in this example provides a ``Stream`` as the body instead of a string. This is a feature or PSR-7 where HTTP message bodies are always represented by streams. This allows you to work with very large bodies without having to store the entire contents in memory. WellRESTed provides ``Stream`` and ``NullStream``, but you can use any implementation of ``Psr\Http\Message\StreamInterface``. Routing by Path ^^^^^^^^^^^^^^^ This is a good start, but it provides the same response to every request. Let's provide this response only when a client sends a request to ``/hello``. For this, we need a router_. A router_ is a special type of middleware_ that examines the request and routes the request through to the middleware that matches. .. _`Example 2`: .. rubric:: Example 2: Routed "Hello, world!" .. code-block:: php createRouter(); // Map middleware to an endpoint and method(s). $router->register("GET", "/hello", function ($request, $response, $next) { // Update the response with the greeting, status, and content-type. $response = $response->withStatus(200) ->withHeader("Content-type", "text/plain") ->withBody(new Stream("Hello, world!")); // Use $next to forward the request on to the next middleware, if any. return $next($request, $response); }); // Add the router to the server. $server->add($router); // Read the request sent to the server and use it to output a response. $server->respond(); Reading Path Variables ^^^^^^^^^^^^^^^^^^^^^^ Routes can be static (like the one above that matches only ``/hello``), or they can be dynamic. Here's an example that uses a dynamic route to read a portion from the path to use as the greeting. For example, a request to ``/hello/Molly`` will respond "Hello, Molly", while a request to ``/hello/Oscar`` will respond "Hello, Oscar!" .. _`Example 3`: .. rubric:: Example 3: Personalized "Hello, world!" .. code-block:: php getAttribute("name", "world"); // Update the response with the greeting, status, and content-type. $response = $response->withStatus(200) ->withHeader("Content-type", "text/plain") ->withBody(new Stream("Hello, $name!")); return $next($request, $response); } // Create the server and router. $server = new Server(); $router = $server->createRouter(); // Register the middleware for an exact match to /hello $router->register("GET", "/hello", $hello); // Register to match a pattern with a variable. $router->register("GET", "/hello/{name}", $hello); $server->add($router); $server->respond(); Multiple Middleware ^^^^^^^^^^^^^^^^^^^ One thing we haven't seen yet is how middleware work together. For the next example, we'll use an additional middleware that sets an ``X-example: hello world``. .. code-block:: php getAttribute("name", "world"); // Set the response body to the greeting and the status code to 200 OK. $response = $response->withStatus(200) ->withHeader("Content-type", "text/plain") ->withBody(new Stream("Hello, $name!")); // Propagate to the next middleware, if any, and return the response. return $next($request, $response); }; // Add a header to the response. $headerAdder = function ($request, $response, $next) { // Add the header. $response = $response->withHeader("X-example", "hello world"); // Propagate to the next middleware, if any, and return the response. return $next($request, $response); }; // Create a server $server = new Server(); // Add $headerAdder to the server first to make it the first to run. $server->add($headerAdder); // When $headerAdder calls $next, it will dispatch the router because it is // added to the server right after. $server->add($server->createRouter() ->register("GET", "/hello", $hello) ->register("GET", "/hello/{name}", $hello) ); // Read the request from the client, dispatch middleware, and output. $server->respond(); .. _middleware: middleware.html .. _router: router.html