Presley is a DSL for quickly creating web applications in PowerShell with minimal effort on Windows:
# myapp.ps1
. .\presley.ps1
get '/' {
'love me tender'
}
run
And start the application:
PS> .\myapp.ps1
View at: http://localhost:9999/
Todo: Next step is to wrap functionalities into a container (either class or module). Then to make it downloadable from PowerShellGallery
In Presley, a route is an HTTP method paired with a URL-matching pattern. Each route is associated with a block:
get '/' {
.. show something ..
}
post '/' {
.. create something ..
}
put '/' {
.. replace something ..
}
delete '/' {
.. annihilate something ..
}
Routes are matched in the order they are defined. The first route that matches the request is invoked.
Route patterns may include named parameters, accessible via the
$params
hash:
get '/hello/:name' {
# matches "GET /hello/foo" and "GET /hello/bar"
# $params['name'] is 'foo' or 'bar'
"Hello $params['name']"
}
You can also access all parameters via param
keyword inside blocks:
get '/hello/:name' {
param($arg)
# matches "GET /hello/foo" and "GET /hello/bar"
# $arg['name'] is 'foo' or 'bar'
"Hello $($arg['name'])!"
}
Routes may also utilize query parameters:
get '/posts' {
# matches "GET /posts?title=foo&author=bar"
$title = $params['title'] # => 'foo'
$author = $params['author'] # => 'bar'
}
$params
contains more than query or path variables: form data in POST/PUT requests.
Further more, pre-defined variable$body
contains content in POST body.
Built-in function halt
can stop processing and respond at once:
get '/halt' {
halt @{code = 404; body = "you'll never find"}
}
Another built-in function, redirect_to
can redirect clients to a relative path:
get '/goto' {
redirect_to '/' # => send 302 and Location='/' to clients
}
The return value of a route block determines at least the response body passed on to the HTTP client.
Most commonly, this is a string, as in the above examples. But other values are also accepted. You can return any object that would either be converted to a string.
Further more, you can return a hashtable with 'headers (hashtable)', 'code (Int)' and 'body (string)', like:
get '/' {
@{
headers = @{ 'Content-Type' = 'application/json' };
code = 200;
body = "{ 'name':'dave', 'age':26 }"
}
}
In PowerShell, the value of the last statement in a block would be the 'return' value of that block.
You can use json
function to quickly create a response hash for JSON data:
get '/date' {
json $(Get-Date)
}
It uses
ConvertTo-Json
cmdlet behind the curtain.
Each template language is exposed via its own rendering method. These methods simply return a string:
get '/' {
eps 'index'
}
This renders template/index.eps
.
Instead of a template name, you can also just pass in the template content directly:
get '/' {
$code = "<%= $(Get-Date).ToString('s') %>"
eps $code
}
This may be not implemented yet.
So far only EPS adapter is implemented. You should install EPS before using this way rendering:
PS> Install-Module EPS
<h1><%= $name %></h1>
<h2><%= $age %></h2>
<ul>
<% 1..5 | % { %>
<li><%= $_ %></li>
<% } %>
</ul>
might output:
<h1>dave</h1>
<h2>26</h2>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
Templates are NOT evaluated within the same context as route handlers. Instance variables set in route handlers should passed to templates:
get '/:id' {
$foo = $params['id']
eps 'products' @{ id = $foo }
}
For more information, please go to project EPS in github
Very similar to Sinatra, other than only returning a string as response body, you can return a hashtable which contains headers, status code and body text:
get '/foo' {
$response = @{}
$response["code"] = 233
$response["headers"] = @{ "Content-Type" = "application/json"; h33 = "2333333"}
$response["body"] = "[{'name':'dave'}, {'name':'davide'}]"
$response
}
Or simply:
get '/bar' {
@{
headers = @{'ContentType' = 'application/json'}
body = "{`"msg`":`"a msg`"}"
}
}
Anything is welcomed.
Author: eyaswoo@gmail.com