Reputation: 858
I'm trying to make a Route Builder in swift using Alamofire (3.0) and I have succeded for all my GET requests, but when I try to make a POST request, for example, I still get the same responses of the GET method.
My API Routes are:
/users //GET -> return list of users
/users //POST -> create new user with the parameters sent
When I use Postman everything works fine.
Here is my Router code:
import Foundation
import Alamofire
enum UserRouter: URLRequestConvertible{
static let baseURL = NSURL(string: "http://192.168.0.106/users")!
case Users
case CreateUser([String: AnyObject])
case ReadUser(Int)
case UpdateUser(Int, [String: AnyObject])
case DestroyUser(Int)
var URL: NSURL { return UserRouter.baseURL.URLByAppendingPathComponent(route.path) }
var route: (path: String, parameters: [String: AnyObject]?) {
switch self{
case .Users:
return ("/", nil)
case .ReadUser(let userID):
return ("/\(userID)", nil)
case .CreateUser(let userInfo):
return ("/", userInfo)
case .UpdateUser(let userID, let userInfo):
return ("/\(userID)", userInfo)
case .DestroyUser(let userID):
return ("/\(userID)", nil)
}
}
var method: Alamofire.Method{
switch self{
case .Users:
return .GET
case .ReadUser:
return .GET
case .CreateUser:
return .POST
case .UpdateUser:
return .PUT
case .DestroyUser:
return .DELETE
}
}
var URLRequest: NSMutableURLRequest {
let httpRequest = NSMutableURLRequest(URL: URL)
httpRequest.HTTPMethod = method.rawValue
switch self{
case .CreateUser (let userInfo):
print("creating")
print(httpRequest.HTTPMethod) //Print: POST on CreateUser, like it should.
return Alamofire.ParameterEncoding.JSON.encode(httpRequest, parameters: userInfo).0
default:
return Alamofire.ParameterEncoding.URL.encode(httpRequest, parameters: (route.parameters ?? [ : ])).0
}
}
}
func testRoute(){
Alamofire.request(UserRouter.CreateUser(["name":"test"])).responseJSON{ (response) in
switch response.result{
case .Success(let data):
print (data) //Error here, printing GET response instead of my API response for creating users (POST).
case .Failure:
print("fail")
}
}
}
Upvotes: 1
Views: 2505
Reputation: 858
Turned out that the problem was a combination of the command that Alamofire.request()
generates (curl -i -X POST...) and how my Apache was handling trailing slashes of the URL. So when I tried to POST "http://192.168.0.106/users"
I was being redirect (301) to a GET "http://192.168.0.106/users"
.
So I had to include this line of command in my .htaccess:
# Redirect Trailing Slashes...
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)/$ /$1 [L,R=301]
and change my Router's code, always appending a trailing slash at the end:
var route: String {
switch self{
case .Users:
return ""
case .ReadUser(let userID):
return "/\(userID)/"
case .CreateUser:
return "/"
case .UpdateUser(let userID):
return "/\(userID)/"
case .DestroyUser(let userID):
return "/\(userID)/"
}
}
Upvotes: 1
Reputation: 437452
This will generate a JSON POST request. Are you sure your web service is expecting a JSON request? Make sure you don't conflate the fact that your web service returns a JSON response with the format of the request.
If your web service is expecting a standard POST request (i.e. a request with a Content-Type
of application/x-www-form-urlencoded
), you'd use URL
for the .CreateUser
, too:
var URLRequest: NSMutableURLRequest {
let httpRequest = NSMutableURLRequest(URL: URL)
httpRequest.HTTPMethod = method.rawValue
switch self {
case .CreateUser (let userInfo):
return Alamofire.ParameterEncoding.URL.encode(httpRequest, parameters: userInfo).0
default:
return Alamofire.ParameterEncoding.URL.encode(httpRequest, parameters: (route.parameters ?? [ : ])).0
}
}
If you ever have questions about whether the request was created correctly, I find that tools like Charles can be useful in confirming the precise request that was sent to the web service.
Upvotes: 0