Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Functions for Handling Route WebEvent Data and Serialization in Pode #1386

Open
wants to merge 28 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
fba1c48
recover from Add Functions for Handling Route WebEvent Data and Seri…
mdaneri Sep 8, 2024
9bfd1d3
additional documentation
mdaneri Sep 11, 2024
6b6f8e2
Improved ConvertTo-PodeSerializedString
mdaneri Sep 15, 2024
c95484b
add rfc6570 link
mdaneri Sep 15, 2024
bd2da28
added URL encoding and decoding
mdaneri Sep 15, 2024
1393558
fix a not completed parameter rename
mdaneri Sep 15, 2024
dde9266
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Sep 15, 2024
3c85f79
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Sep 21, 2024
fbbe84d
Merge branch 'develop' into Pode-webeventData
mdaneri Sep 22, 2024
095f420
Merge branch 'develop' into Pode-webeventData
mdaneri Sep 22, 2024
a6c756a
Merge branch 'develop' into Pode-webeventData
mdaneri Sep 26, 2024
cbfd484
Merge branch 'develop' into Pode-webeventData
mdaneri Sep 28, 2024
e81dcf0
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Sep 28, 2024
97d053e
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Sep 28, 2024
a681b54
Merge branch 'develop' into Pode-webeventData
mdaneri Sep 29, 2024
4b137ff
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Oct 16, 2024
9776d34
Merge branch 'develop' into Pode-webeventData
mdaneri Oct 19, 2024
5cb2c3d
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Oct 20, 2024
5c5059a
Update Utilities.ps1
mdaneri Oct 21, 2024
1775962
Merge branch 'develop' into Pode-webeventData
mdaneri Oct 21, 2024
562196e
Merge branch 'develop' into Pode-webeventData
mdaneri Oct 23, 2024
6ab1f7c
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Oct 23, 2024
edd1ed4
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Oct 27, 2024
6ee3a02
Merge branch 'develop' into Pode-webeventData
mdaneri Oct 28, 2024
5a044ac
Merge branch 'develop' into Pode-webeventData
mdaneri Oct 30, 2024
76d2583
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Nov 2, 2024
5409b1e
Merge remote-tracking branch 'upstream/develop' into Pode-webeventData
mdaneri Nov 3, 2024
fde4c8e
Merge branch 'develop' into Pode-webeventData
mdaneri Nov 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 8 additions & 83 deletions docs/Tutorials/Routes/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,96 +39,21 @@ The scriptblock for the route will have access to the `$WebEvent` variable which

You can add your routes straight into the [`Start-PodeServer`](../../../Functions/Core/Start-PodeServer) scriptblock, or separate them into different files. These files can then be dot-sourced, or you can use [`Use-PodeRoutes`](../../../Functions/Routes/Use-PodeRoutes) to automatically load all ps1 files within a `/routes` directory at the root of your server.

## Payloads
## Retrieving Client Parameters

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.
When working with REST calls, data can be passed by the client using various methods, including Cookies, Headers, Paths, Queries, and Body. Each of these methods has specific ways to retrieve the data:

Depending the the Content-Type supplied, Pode has inbuilt body-parsing logic for JSON, XML, CSV, and Form data.
- **Cookies**: Cookies sent by the client can be accessed using the `$WebEvent.Cookies` property or the `Get-PodeCookie` function for more advanced handling. For more details, refer to the [Cookies Documentation](./Parameters/Cookies.md).

This example will get the `userId` and "find" user, returning the users data:
- **Headers**: Headers can be retrieved using the `$WebEvent.Request.Headers` property or the `Get-PodeHeader` function, which provides additional deserialization options. Learn more in the [Headers Documentation](./Parameters/Headers.md).

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
- **Paths**: Parameters passed through the URL path can be accessed using the `$WebEvent.Parameters` property or the `Get-PodePathParameter` function. Detailed information can be found in the [Path Parameters Documentation](./Parameters/Paths.md).

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:

```powershell
Invoke-WebRequest -Uri 'http://localhost:8080/users' -Method Post -Body '{ "userId": 12345 }' -ContentType 'application/json'
```
- **Queries**: Query parameters from the URL can be accessed via `$WebEvent.Query` or retrieved using the `Get-PodeQueryParameter` function for deserialization support. Check the [Query Parameters Documentation](./Parameters/Queries.md).

!!! 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.
- **Body**: Data sent in the request body, such as in POST requests, can be retrieved using the `$WebEvent.Data` property or the `Get-PodeBodyData` function for enhanced deserialization capabilities. See the [Body Data Documentation](./Parameters/Body.md) for more information.

!!! 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:

```powershell
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:

```powershell
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:

```powershell
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:

```powershell
Invoke-WebRequest -Uri 'http://localhost:8080/users/12345' -Method Get
```
Each link provides detailed usage and examples to help you retrieve and manipulate the parameters passed by the client effectively.

## Script from File

Expand Down
100 changes: 100 additions & 0 deletions docs/Tutorials/Routes/Parameters/Body.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Body Payloads

The following is an example of using data from a request's payload—i.e., the data in the body of a POST request. To retrieve values from the payload, you can use the `.Data` property on the `$WebEvent` variable in a route's logic.

Alternatively, you can use the `Get-PodeBodyData` function to retrieve the body data, with additional support for deserialization.

Depending on the Content-Type supplied, Pode has built-in body-parsing logic for JSON, XML, CSV, and Form data.

This example will get the `userId` and "find" the user, returning the user's data:

```powershell
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:

```powershell
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 request's payload. For example, if the content type is `application/json`, 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+.

### Using Get-PodeBodyData

Alternatively, you can use the `Get-PodeBodyData` function to retrieve the body data. This function works similarly to the `.Data` property on `$WebEvent` and supports the same content types.

Here is the same example using `Get-PodeBodyData`:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http

Add-PodeRoute -Method Post -Path '/users' -ScriptBlock {
# get the body data
$body = Get-PodeBodyData

# get the user
$user = Get-DummyUser -UserId $body.userId

# return the user
Write-PodeJsonResponse -Value @{
Username = $user.username
Age = $user.age
}
}
}
```

### Deserialization with Get-PodeBodyData

Typically the request body is encoded in Json,Xml or Yaml but if it's required the `Get-PodeBodyData` function can also deserialize body data from requests, allowing for more complex data handling scenarios where the only allowed ContentTypes are `application/x-www-form-urlencoded` or `multipart/form-data`. This feature can be especially useful when dealing with serialized data structures that require specific interpretation styles.

To enable deserialization, use the `-Deserialize` switch along with the following options:

- **`-NoExplode`**: Prevents deserialization from exploding arrays in the body data. This is useful when dealing with comma-separated values where array expansion is not desired.
- **`-Style`**: Defines the deserialization style (`'Simple'`, `'Label'`, `'Matrix'`, `'Form'`, `'SpaceDelimited'`, `'PipeDelimited'`, `'DeepObject'`) to interpret the body data correctly. The default style is `'Form'`.
- **`-KeyName`**: Specifies the key name to use when deserializing, allowing accurate mapping of the body data. The default value for `KeyName` is `'id'`.

### Example with Deserialization

This example demonstrates deserialization of body data using specific styles and options:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http

Add-PodeRoute -Method Post -Path '/items' -ScriptBlock {
# retrieve and deserialize the body data
$body = Get-PodeBodyData -Deserialize -Style 'Matrix' -NoExplode

# get the item based on the deserialized data
$item = Get-DummyItem -ItemId $body.id

# return the item details
Write-PodeJsonResponse -Value @{
Name = $item.name
Quantity = $item.quantity
}
}
}
```

In this example, `Get-PodeBodyData` is used to deserialize the body data with the `'Matrix'` style and prevent array explosion (`-NoExplode`). This approach provides flexible and precise handling of incoming body data, enhancing the capability of your Pode routes to manage complex payloads.
107 changes: 107 additions & 0 deletions docs/Tutorials/Routes/Parameters/Cookies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@

# Cookies

The following is an example of using values supplied in a request's cookies. To retrieve values from the cookies, you can use the `Cookies` property from the `$WebEvent` variable.

Alternatively, you can use the `Get-PodeCookie` function to retrieve the cookie data, with additional support for deserialization and secure handling.

This example will get the `SessionId` cookie and use it to authenticate the user, returning a success message:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http

Add-PodeRoute -Method Get -Path '/authenticate' -ScriptBlock {
# get the session ID from the cookie
$sessionId = $WebEvent.Cookies['SessionId']

# authenticate the session
$isAuthenticated = Authenticate-Session -SessionId $sessionId

# return the result
Write-PodeJsonResponse -Value @{
Authenticated = $isAuthenticated
}
}
}
```

The following request will invoke the above route:

```powershell
Invoke-WebRequest -Uri 'http://localhost:8080/authenticate' -Method Get -Headers @{ Cookie = 'SessionId=abc123' }
```

## Using Get-PodeCookie

Alternatively, you can use the `Get-PodeCookie` function to retrieve the cookie data. This function works similarly to the `Cookies` property on `$WebEvent`, but it provides additional options for deserialization and secure cookie handling.

Here is the same example using `Get-PodeCookie`:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http

Add-PodeRoute -Method Get -Path '/authenticate' -ScriptBlock {
# get the session ID from the cookie
$sessionId = Get-PodeCookie -Name 'SessionId'

# authenticate the session
$isAuthenticated = Authenticate-Session -SessionId $sessionId

# return the result
Write-PodeJsonResponse -Value @{
Authenticated = $isAuthenticated
}
}
}
```

### Deserialization with Get-PodeCookie

The `Get-PodeCookie` function can also deserialize cookie values, allowing for more complex handling of serialized data sent in cookies. This feature is particularly useful when cookies contain encoded or structured content that needs specific parsing.

To enable deserialization, use the `-Deserialize` switch along with the following options:

- **`-NoExplode`**: Prevents deserialization from exploding arrays in the cookie value. This is useful when handling comma-separated values where array expansion is not desired.
- **`-Deserialize`**: Indicates that the retrieved cookie value should be deserialized, interpreting the content based on the provided deserialization style and options.



#### Supported Deserialization Styles

| Style | Explode | URI Template | Primitive Value (id = 5) | Array (id = [3, 4, 5]) | Object (id = {"role": "admin", "firstName": "Alex"}) |
|-------|---------|--------------|--------------------------|------------------------|------------------------------------------------------|
| form* | true* | | Cookie: id=5 | | |
| form | false | id={id} | Cookie: id=5 | Cookie: id=3,4,5 | Cookie: id=role,admin,firstName,Alex |

\* Default serialization method

### Example with Deserialization

This example demonstrates deserialization of a cookie value:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http

Add-PodeRoute -Method Get -Path '/deserialize-cookie' -ScriptBlock {
# retrieve and deserialize the 'Session' cookie
$sessionData = Get-PodeCookie -Name 'Session' -Deserialize -NoExplode

# process the deserialized cookie data
# (example processing logic here)

# return the processed cookie data
Write-PodeJsonResponse -Value @{
SessionData = $sessionData
}
}
}
```

In this example, `Get-PodeCookie` is used to deserialize the `Session` cookie, interpreting it according to the provided deserialization options. The `-NoExplode` switch ensures that any arrays within the cookie value are not expanded during deserialization.

For further information regarding serialization, please refer to the [RFC6570](https://tools.ietf.org/html/rfc6570).

For further information on general usage and retrieving cookies, please refer to the [Headers Documentation](Cookies.md).
Loading