Alamofire: Requests, Validation & Decoding
Alamofire is a Swift HTTP networking library built on top of URLSession — not a replacement for it. It adds a chainable, ergonomic API for requests, validation, response serialization, and common patterns like multipart uploads and auth interceptors.
Basic Requests
import Alamofire
struct User: Decodable {
let id: Int
let name: String
let email: String
}
// AF is Alamofire's default shared Session instance
AF.request("https://api.example.com/users/1")
.validate() // non-2xx status codes become errors, not silent "success"
.responseDecodable(of: User.self) { response in
switch response.result {
case .success(let user):
print(user.name)
case .failure(let error):
print("Request failed: \(error)")
}
}
// async/await style (Alamofire 5+)
func fetchUser(id: Int) async throws -> User {
try await AF.request("https://api.example.com/users/\(id)")
.validate()
.serializingDecodable(User.self)
.value
}
// Debugging: print an equivalent curl command for this exact request
AF.request("https://api.example.com/users/1").cURLDescription { description in
print(description)
}Parameters, Methods & Headers
struct NewPost: Encodable {
let title: String
let body: String
}
// POST with a JSON-encoded body
let post = NewPost(title: "Hello", body: "World")
AF.request(
"https://api.example.com/posts",
method: .post,
parameters: post,
encoder: JSONParameterEncoder.default,
headers: ["Authorization": "Bearer \(token)"]
)
.validate()
.responseDecodable(of: Post.self) { response in }
// GET with query-string parameters
AF.request(
"https://api.example.com/search",
parameters: ["q": "swift", "page": 2],
encoding: URLEncoding.default // -> ?q=swift&page=2
)
// Cancelling an in-flight request (e.g. superseded by a newer search)
var currentSearch: DataRequest?
func search(_ query: String) {
currentSearch?.cancel()
currentSearch = AF.request("https://api.example.com/search", parameters: ["q": query])
}Structuring Endpoints with URLRequestConvertible
// Centralize endpoint definitions instead of scattering ad-hoc AF.request calls
enum API: URLRequestConvertible {
case getUser(id: Int)
case createPost(NewPost)
var baseURL: URL { URL(string: "https://api.example.com")! }
var path: String {
switch self {
case .getUser(let id): return "/users/\(id)"
case .createPost: return "/posts"
}
}
var method: HTTPMethod {
switch self {
case .getUser: return .get
case .createPost: return .post
}
}
func asURLRequest() throws -> URLRequest {
var request = URLRequest(url: baseURL.appendingPathComponent(path))
request.method = method
if case .createPost(let post) = self {
request = try JSONParameterEncoder.default.encode(post, into: request)
}
return request
}
}
AF.request(API.getUser(id: 1)).responseDecodable(of: User.self) { response in }Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free