4

I'm writing a web service using Vapor framework in Swift.

In my app, I have User model. The following is how I route a get request for all users.

router.get("users") { request in
    return User.query(on: request).all()
}

After running the server locally, to get the users, I can make a request like localhost:8080/users

Now, I want to add parameter to the request to get users above the given age. The request will look like localhost:8080/users?above_age=25

How to add the parameter in the request using the Vapor framework? I tried with the available docs but I can't figure it.

Since I am now starting with Server Side Swift using Vapor, any reference to resources using Vapor 3 will also be of help for other issues I might face. Thanks!

imthath
  • 1,353
  • 1
  • 13
  • 35

2 Answers2

5

The query string parameters will be in the query container and hence they can accessed like below.

router.get("users") { request -> Future<[User]> in
    if let minimumAge = request.query[Int.self, at: "above_age"] {
        return User.query(on: request).filter(\.age > minimumAge).all()
    }
    return User.query(on: request).all()
}

If the request has above_age as a query param, the router will return list of users above that age else it will return all users.

imthath
  • 1,353
  • 1
  • 13
  • 35
3

Common code:

struct UserFormInput: Codable {
    let aboveAge: UInt

    enum CodingKeys: String, CodingKey {
        case aboveAge= "above_age"
    }
}

Use GET with slug format (not the best fit for this use case):

localhost:8080/users/above_age/25

router.get("users", "above_age", Int.parameter) { req in
    let age = try req.parameters.next(Int.self)
    return "user id: \(age)"
}

References:


Using GET with URL encoded parameters (updated using previous answer):

localhost:8080/users?above_age=25

router.get("users") { request -> Future<[User]> in
    let minimumAge = try? request.query.get(Int.self, at: "above_age")
    // do something
}

OR

router.get("users") { request -> Future<[User]> in
    let userQuery = try req.query.decode(UserFormInput.self)
    // do something
}

References:


Using POST:

router.post("users") { req in
    return try req.content.decode(UserFormInput.self)
            .flatMap { input in
                return // do something
            }
}

References:

nathan
  • 9,329
  • 4
  • 37
  • 51
  • thanks for the answer nathan. but both options are workarounds for the functionality and not what I actually asked(using query string parameters). Fortunately, I've found it from the vapor community and I am adding the same as answer. – imthath Apr 28 '19 at 15:18
  • 1
    Been using Vapor for 1 year or so, didn't realize about the req.query method. Thanks for the update ! – nathan Apr 28 '19 at 17:14