Overview
Routes in Pode allow you to bind logic that should be invoked when a users call certain paths on a URL, for a specific HTTP method, against your server. Routes allow you to host REST APIs and Web Pages, as well as using custom Middleware for logic such as authentication.
You can also create static routes, that redirect requests for static content to internal directories.
Routes can also be bound against a specific protocol or endpoint. This allows you to bind multiple root (/
) routes against different endpoints - if you're listening to multiple endpoints.
Info
The following HTTP methods are supported by routes in Pode: DELETE, GET, HEAD, MERGE, OPTIONS, PATCH, POST, PUT, and TRACE.
Usage
To setup and use Routes in Pode you should use the Routing functions. For example, let's say you want a basic GET /ping
endpoint to just return pong
as a JSON response:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/ping' -ScriptBlock {
Write-PodeJsonResponse -Value @{ 'value' = 'pong'; }
}
}
Here, anyone who calls http://localhost:8080/ping
will receive the following response:
{
"value": "pong"
}
The scriptblock for the route will have access to the $WebEvent
variable which contains information about the current web event. This argument will contain the Request
and Response
objects, Data
(from POST), and the Query
(from the query string of the URL), as well as any Parameters
from the route itself (eg: /:accountId
).
You can add your routes straight into the Start-PodeServer
scriptblock, or separate them into different files. These files can then be dot-sourced, or you can use Use-PodeRoutes
to automatically load all ps1 files within a /routes
directory at the root of your server.
Payloads
The following is an example of using data from a request's payload - ie, the data in the body of POST request. To retrieve values from the payload you can use the .Data
property on the $WebEvent
variable to a route's logic.
Depending the the Content-Type supplied, Pode has inbuilt body-parsing logic for JSON, XML, CSV, and Form data.
This example will get the userId
and "find" user, returning the users data:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeRoute -Method Post -Path '/users' -ScriptBlock {
# get the user
$user = Get-DummyUser -UserId $WebEvent.Data.userId
# return the user
Write-PodeJsonResponse -Value @{
Username = $user.username
Age = $user.age
}
}
}
The following request will invoke the above route:
Invoke-WebRequest -Uri 'http://localhost:8080/users' -Method Post -Body '{ "userId": 12345 }' -ContentType 'application/json'
Important
The ContentType
is required as it informs Pode on how to parse the requests payload. For example, if the content type were application/json
, then Pode will attempt to parse the body of the request as JSON - converting it to a hashtable.
Important
On PowerShell 5 referencing JSON data on $WebEvent.Data
must be done as $WebEvent.Data.userId
. This also works in PowerShell 6+, but you can also use $WebEvent.Data['userId']
on PowerShell 6+.
Query Strings
The following is an example of using data from a request's query string. To retrieve values from the query string you can use the .Query
property from the $WebEvent
variable. This example will return a user based on the userId
supplied:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/users' -ScriptBlock {
# get the user
$user = Get-DummyUser -UserId $WebEvent.Query['userId']
# return the user
Write-PodeJsonResponse -Value @{
Username = $user.username
Age = $user.age
}
}
}
The following request will invoke the above route:
Invoke-WebRequest -Uri 'http://localhost:8080/users?userId=12345' -Method Get
Parameters
The following is an example of using values supplied on a request's URL using parameters. To retrieve values that match a request's URL parameters you can use the .Parameters
property from the $WebEvent
variable. This example will get the :userId
and "find" user, returning the users data:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/users/:userId' -ScriptBlock {
# get the user
$user = Get-DummyUser -UserId $WebEvent.Parameters['userId']
# return the user
Write-PodeJsonResponse -Value @{
Username = $user.username
Age = $user.age
}
}
}
The following request will invoke the above route:
Invoke-WebRequest -Uri 'http://localhost:8080/users/12345' -Method Get
Script from File
You normally define a route's script using the -ScriptBlock
parameter however, you can also reference a file with the required scriptblock using -FilePath
. Using the -FilePath
parameter will dot-source a scriptblock from the file, and set it as the route's script.
For example, to create a route from a file that will write a simple JSON response on a route:
-
File.ps1
{ Write-PodeJsonResponse -Value @{ 'value' = 'pong'; } }
-
Route
Add-PodeRoute -Method Get -Path '/ping' -FilePath './Routes/File.ps1'
Getting Routes
There are two helper function that allow you get retrieve a list of routes, and filter routes as well: Get-PodeRoute
and Get-PodeStaticRoute
.
You can use these functions to retrieve all routes, or routes for a specific HTTP method, path, endpoint, etc.
To retrieve all routes, you can call the functions with no parameters. To filter, here are some examples:
# all routes for method
Get-PodeRoute -Method Get
# all routes for a Path
Get-PodeRoute -Path '/users'
# all routes for an Endpoint by name
Get-PodeRoute -EndpointName Admin
The Get-PodeStaticRoute
function works in the same way as above - but with no -Method
parameter.
Grouping
If you have a number of Routes that all share the same base path, middleware, authentication, or other parameters, then you can add these Routes within a Route Group (via Add-PodeRouteGroup
) to share the parameter values:
Add-PodeRouteGroup -Path '/api' -Authentication Basic -Routes {
Add-PodeRoute -Method Get -Path '/route1' -ScriptBlock {
Write-PodeJsonResponse -Value @{ ID = 1 }
}
Add-PodeRoute -Method Get -Path '/route2' -ScriptBlock {
Write-PodeJsonResponse -Value @{ ID = 2 }
}
Add-PodeRoute -Method Get -Path '/route3' -ScriptBlock {
Write-PodeJsonResponse -Value @{ ID = 3 }
}
}
In the above example, this will create 3 Routes: /api/route1
, /api/route2
, and /api/route3
. Each of the Routes will also all require some Basic authentication.
You can also do the same with Static and Signal Routes via Add-PodeStaticRouteGroup
and Add-PodeSignalRouteGroup
.
More information on Route grouping can be found here.
Route Object
Warning
Be careful if you choose to edit these objects, as they will affect the server.
The following is the structure of the Route object internally, as well as the object that is returned from Add-PodeRoute -PassThru
or Get-PodeRoute
:
Name | Type | Description |
---|---|---|
Arguments | object[] | Array of arguments that are splatted onto the route's scriptblock |
ContentType | string | The content type to use when parsing the payload in the request |
Endpoint | hashtable | Contains the Address, Protocol, and Name of the Endpoint the route is bound to |
ErrorType | string | Content type of the error page to use for the route |
IsStatic | bool | Fixed to false for normal routes |
Logic | scriptblock | The main scriptblock logic of the route |
Method | string | HTTP method of the route |
Metrics | hashtable | Metrics for the route, such as Request counts |
Middleware | hashtable[] | Array of middleware that runs prior to the route's scriptblock |
OpenApi | hashtable[] | The OpenAPI definition/settings for the route |
Path | string | The path of the route - this path will have regex in place of route parameters |
TransferEncoding | string | The transfer encoding to use when parsing the payload in the request |
Static routes have a slightly different format:
Name | Type | Description |
---|---|---|
ContentType | string | Content type to use when parsing the payload a request to the route |
Defaults | string[] | Array of default file names to render if path in request is a folder |
Download | bool | Specifies whether files are rendered in the response, or downloaded |
Endpoint | hashtable | Contains the Address, Protocol, and Name of the Endpoint the route is bound to |
ErrorType | string | Content type of the error page to use for the route |
IsStatic | bool | Fixed to true for static routes |
Method | string | HTTP method of the route |
Metrics | hashtable | Metrics for the route, such as Request counts |
Middleware | hashtable[] | Array of middleware that runs prior to the route's scriptblock |
OpenApi | hashtable[] | The OpenAPI definition/settings for the route |
Path | string | The path of the route - this path will have regex in place of dynamic file names |
Source | string | The source path within the server that is used for the route |
TransferEncoding | string | The transfer encoding to use when parsing the payload in the request |