mirror of https://github.com/vapor/docs.git
add url-encoded form docs
This commit is contained in:
parent
f49086b4fa
commit
7d2fb87258
|
|
@ -0,0 +1,42 @@
|
|||
# Getting Started with URL-Encoded Form
|
||||
|
||||
URL-Encoded Form ([vapor/url-encoded-form](https://github.com/vapor/url-encoded-form)) is a small package that helps you parse and serialize `application/x-www-form-urlencoded` data. URL-encoded forms are a widely-supported encoding on the web. It's most often used for serializing web forms sent via POST requests.
|
||||
|
||||
The URL-Encoded Form package makes it easy to use this encoding by integrating directly with `Codable`.
|
||||
|
||||
## Vapor
|
||||
|
||||
This package is included with Vapor and exported by default. You will have access to all `URLEncodedForm` APIs when you import `Vapor`.
|
||||
|
||||
```swift
|
||||
import Vapor
|
||||
```
|
||||
|
||||
## Standalone
|
||||
|
||||
The URL-Encoded Form package is lightweight, pure-Swift, and has very few dependencies. This means it can be used to work with `form-urlencoded` data for any Swift project—even one not using Vapor.
|
||||
|
||||
To include it in your package, add the following to your `Package.swift` file.
|
||||
|
||||
```swift
|
||||
// swift-tools-version:4.0
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Project",
|
||||
dependencies: [
|
||||
...
|
||||
.package(url: "https://github.com/vapor/url-encoded-form.git", from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Project", dependencies: ["URLEncodedForm", ... ])
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
Use `import URLEncodedForm` to access the APIs.
|
||||
|
||||
!!! warning
|
||||
Some of this guide may contain Vapor-specific APIs, however most of it should be applicable to the URL-Encoded Form package in general.
|
||||
Visit the [API Docs](https://api.vapor.codes/url-encoded-form/latest/URLEncodedForm/index.html) for specific API info.
|
||||
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
# Using URL-Encoded Form
|
||||
|
||||
URL-Encoded Form is a widely-supported encoding on the web. It's most often used for serializing web forms sent via POST requests. This encoding is also used to send structured data in URL query strings.
|
||||
|
||||
It is a relatively efficient encoding for sending small amounts of data. However, all data must be percent-encoded making this encoding suboptimal for large amounts of data. See the [Multipart](../multipart/getting-started.md) encoding if you need to upload things like files.
|
||||
|
||||
!!! tip
|
||||
URL-Encoded Form integrates with [`Content`](https://api.vapor.codes/vapor/latest/Vapor/Protocols/Content.html) like all other encoding methods in Vapor. See [Vapor → Content](../vapor/content.md) for more information about the [`Content`](https://api.vapor.codes/vapor/latest/Vapor/Protocols/Content.html) protocol.
|
||||
|
||||
Let's take a look at how to decode a `application/x-www-form-urlencoded` request.
|
||||
|
||||
## Decode Body
|
||||
|
||||
Most often, you will be decoding `form-urlencoded`-encoded requests from a web form. Let's take a look at what one of these requests might look like. After that, we will take a look at what the HTML form for that request would look like.
|
||||
|
||||
### Request
|
||||
|
||||
Here is an example `form-urlencoded`-encoded request for creating a new user.
|
||||
|
||||
```http
|
||||
POST /users HTTP/1.1
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
name=Vapor&age=3&luckyNumbers[]=5&luckyNumbers[]=7
|
||||
```
|
||||
|
||||
You can see the `[]` notation is used to encode arrays. Your web form will need to use this notation as well.
|
||||
|
||||
### Form
|
||||
|
||||
There are many ways to create a `form-urlencoded`-encoded request, but the most common is an HTML web form. Here is what the HTML form for this request might have looked like.
|
||||
|
||||
```html
|
||||
<form method="POST" action="/users">
|
||||
<input type="text" name="name">
|
||||
<input type="text" name="age">
|
||||
<input type="text" name="luckyNumbers[]">
|
||||
<input type="text" name="luckyNumbers[]">
|
||||
</form>
|
||||
```
|
||||
|
||||
Since we are not specifying a special `enctype` attribute on the `<form>`, the browser will URL-encode the form by default. We are also providing two fields with the same name, `luckyNumbers[]`. This will let us send an array of values.
|
||||
|
||||
### Content
|
||||
|
||||
Now let's take a look at how we would handle this request in Vapor. The first step (as always with [`Content`](https://api.vapor.codes/vapor/latest/Vapor/Protocols/Content.html)) is to create a `Codable` struct that represents the data structure.
|
||||
|
||||
```swift
|
||||
import Vapor
|
||||
|
||||
struct User: Content {
|
||||
var name: String
|
||||
var age: Int
|
||||
var luckyNumbers: [Int]
|
||||
}
|
||||
```
|
||||
|
||||
Now that we have our `User` struct, let's decode that request! We can use the [`ContentContainer`](https://api.vapor.codes/vapor/latest/Vapor/Structs/ContentContainer.html) to do this easily.
|
||||
|
||||
```swift
|
||||
router.post("users") { req -> Future<HTTPStatus> in
|
||||
return try req.content.decode(User.self).map(to: HTTPStatus.self) { user in
|
||||
print(user.name) // "Vapor"
|
||||
print(user.age) // 3
|
||||
print(user.luckyNumbers) // [5, 7]
|
||||
return .ok
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now when you post the form to `/users`, you should see the information printed in the console. Nice work!
|
||||
|
||||
## Encode Body
|
||||
|
||||
APIs encode `form-urlencoded` data much less often than they decode it. However, encoding is just as easy with Vapor. Using our same `User` struct from the previous example, here is how we can encode a `form-urlencoded`-encoded response.
|
||||
|
||||
```swift
|
||||
router.get("multipart") { req -> User in
|
||||
let res = req.makeResponse()
|
||||
let user = User(name: "Vapor", age: 3, luckyNumbers: [5, 7])
|
||||
res.content.encode(user, as: .urlEncodedForm)
|
||||
return user
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
If you set a default `MediaType` on your `Content` types, then you can return them directly in the route closure.
|
||||
|
||||
## URL Query
|
||||
|
||||
URL-Encoded Forms are also useful for sending structured data in the URL query string. This is widely used for sending data via GET requests where HTTP bodies are not allowed.
|
||||
|
||||
Let's take a look at how we can decode some search parameters from the query string.
|
||||
|
||||
```http
|
||||
GET /users?name=Vapor&age=3 HTTP/1.1
|
||||
```
|
||||
The first step (as always with [`Content`](https://api.vapor.codes/vapor/latest/Vapor/Protocols/Content.html)) is to create a `Codable` struct that represents the data structure.
|
||||
|
||||
```swift
|
||||
import Vapor
|
||||
|
||||
struct UsersFilters: Content {
|
||||
var name: String?
|
||||
var age: Int?
|
||||
}
|
||||
```
|
||||
|
||||
Here we are making both `name` and `age` optional since the route can be called without any flags to return all users.
|
||||
|
||||
Now that we have a `Codable` struct, we can decode the URL query string. The process is almost identical to decoding content, expect we use `req.query` instead of `req.content`.
|
||||
|
||||
```swift
|
||||
router.get("users") { req -> Future<[User]> in
|
||||
let filters = try req.query.decode(UsersFilters.self)
|
||||
print(filters.name) // Vapor
|
||||
print(filters.age) // 3
|
||||
return // fetch users with filters
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Decoding the URL query string is not asynchronous because, unlike HTTP bodies, Vapor can be sure it is available when calling the route closure.
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Using Content
|
||||
|
||||
In Vapor 3, all content types (JSON, protobuf, URLEncodedForm, [Multipart](../multipart/getting-started.md), etc) are treated the same. All you need to parse and serialize content is a `Codable` class or struct.
|
||||
In Vapor 3, all content types (JSON, protobuf, [URLEncodedForm](../url-encoded-form/getting-started.md), [Multipart](../multipart/getting-started.md), etc) are treated the same. All you need to parse and serialize content is a `Codable` class or struct.
|
||||
|
||||
For this introduction, we will use JSON as an example. But keep in mind the API is the same for any supported content type.
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ pages:
|
|||
- 'Getting Started': 'template-kit/getting-started.md'
|
||||
- 'Testing':
|
||||
- 'Getting Started': 'testing/getting-started.md'
|
||||
- 'URL-Encoded Form':
|
||||
- 'Getting Started': 'url-encoded-form/getting-started.md'
|
||||
- 'Overview': 'url-encoded-form/overview.md'
|
||||
- 'Validation':
|
||||
- 'Getting Started': 'validation/getting-started.md'
|
||||
- 'Overview': 'validation/overview.md'
|
||||
|
|
|
|||
Loading…
Reference in New Issue