Skip to content
This repository has been archived by the owner on Dec 8, 2021. It is now read-only.

Add middleware support to polaris #49

Merged
merged 4 commits into from
Oct 23, 2017
Merged

Conversation

TylerLeonhardt
Copy link
Member

@TylerLeonhardt TylerLeonhardt commented Oct 21, 2017

Middleware Support in Polaris

This PR contains the code to enable middleware in Polaris - with it comes BREAKING CHANGES

What is Middleware?

Middleware is a concept that's been around for quite some time. In web frameworks, middleware is code that is able to manipulate the request that comes in before it hits your route logic. For Polaris, middleware gets run AFTER a request comes in, but BEFORE your route script block is run - hence, MIDDLEware.

I'll go into an example but first I need to talk about an important BREAKING CHANGE.

Breaking Changes

There are 2 major breaking changes.

  • Route (and Middleware) scripts do not need the param($request, $response) line at the top of the script. These parameters are made global in the scope of the script and will exist without this param line. This means that YOU MUST REMOVE THIS LINE WITH THESE CHANGES. Why? Because the global params are $Request and $Response. If you have param($request, $response), that will take priority over the global params and what you will have instead is two null variables. REMOVE THAT LINE. It's much easier if you do. 😄
  • $request.QueryParameters has been renamed to $request.Query because "Parameters" is a very long word.

Ok. On to that example. Did you remove those param lines yet? Do it. Seriously.

Example

A very important middleware for Polaris is a JSON body parser. This will take the stream of the HTTP body (which is a string representation of the JSON body) and convert it into a PowerShell object to allow us to interact with the body data. Let's write a middleware that does this.

Like our Route scripts, the middleware is also just a PowerShell script:

New-PolarisRouteMiddleware - Name JsonBodyParser -ScriptBlock {
    if ($Request.BodyString -ne $null) {
        $Request.Body = $Request.BodyString | ConvertFrom-Json
    }
}

Now that $Request is made available globally, we can check if the raw body string exists. If it does, we can parse that string and store it in the $Request.Body.

Then, we're able to use this body in our Route scripts like so:

New-PolarisPostRoute -Path "/hello" -ScriptBlock {
    if ($request.Body.Name) {
        $response.Send('Hello ' + $request.Body.Name);
    } else {
        $response.Send('Hello World');
    }
}

When you do an Invoke-RestMethod you get the expected result:

PS > Invoke-RestMethod -Uri http://localhost:8080/hello -Method POST -Body '{"Name":"Atlas"}' -ContentType application/json
Hello Atlas

It's really simple to get started. You can add any number of middlewares - they will be run in the order that they are added to Polaris.

But of course, since a JSON Body parser will be used in a lot of situations, we have one built in. All you have to do is flip the switch.

When you're ready to start your server, add this flag and it will turn on that exact middleware code above:

Start-Polaris -UseJsonBodyParserMiddleware

or use the helper cmdlet: Use-JsonBodyParserMiddleware

Misc

This PR also includes helper cmdlets to:

  • delete middleware - Remove-PolarisRouteMiddleware
  • delete routes - Remove-PolarisWebRoute
  • get the route dictionary - Get-PolarisWebRoute
  • get the middleware by name - Get-PolarisRouteMiddleware

That's all for now. We're really excited to see what you come up with - using middleware.

Tyler

@sgnewman
Copy link

sgnewman commented May 1, 2018

The cmdlet seems to be named incorrectly in the example above:

New-RouteMiddleware - Name JsonBodyParser -ScriptBlock { if ($Request.BodyString -ne $null) { $Request.Body = $Request.BodyString | ConvertFrom-Json } }

should it not be:
New-PolarisRouteMiddleware - Name JsonBodyParser -ScriptBlock { if ($Request.BodyString -ne $null) { $Request.Body = $Request.BodyString | ConvertFrom-Json } }

The cmdlets referenced in the Misc. section seem to be named incorrectly as well.

Also, this is friggin awesome.

@TylerLeonhardt
Copy link
Member Author

This was back before the Polaris prefix :) but it's fixed now!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants