I had a very basic Flask server while developing my apis locally and now it’s time to port them over to AWS Lambda which I’ve done so using serverless
to get everything deployed through configuration files without any problems.
Is this the only route I can go? https://docs.amplify.aws/swift/build-a-backend/auth/use-existing-cognito-resources/#use-auth-resources-without-an-amplify-backend ?
Is it possible to not rely on 3rd party libraries and directly call the API Gateway url in Swift, somehow? Something like this:
<code>class APIGatewayManager {
static let shared = APIGatewayManager()
private let baseURL: String
self.baseURL = "https://abc123def.execute-api.us-west-2.amazonaws.com/dev"
func makeAPICall<T: Codable>(path: String, method: String, body: [String: Any]? = nil) async throws -> T {
guard let url = URL(string: baseURL + path) else {
throw APIError.invalidURL
var request = URLRequest(url: url)
request.httpMethod = method
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
throw APIError.invalidResponse
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
class ProfilesViewModel: ObservableObject {
func fetchProfiles() async {
let profiles: [DecodableProfile] = try await APIGatewayManager.shared.makeAPICall(path: "/profiles", method: "GET")
self.profiles = profiles.map { $0.toProfile() }
self.showToastMessage("Fetched profiles successfully", isSuccess: true)
self.showToastMessage("Error fetching profiles: (error.localizedDescription)", isSuccess: false)
func updateProfile(_ profile: Profile) async {
let updatedProfile: DecodableProfile = try await APIGatewayManager.shared.makeAPICall(
path: "/profiles/(profile.id)",
body: profile.toDecodableProfile().dictionary
if let index = self.profiles.firstIndex(where: { $0.id == updatedProfile.id }) {
self.profiles[index] = updatedProfile.toProfile()
self.showToastMessage("Profile updated successfully", isSuccess: true)
self.showToastMessage("Error updating profile: (error.localizedDescription)", isSuccess: false)
var dictionary: [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String: Any]
<code>class APIGatewayManager {
static let shared = APIGatewayManager()
private let baseURL: String
private init() {
self.baseURL = "https://abc123def.execute-api.us-west-2.amazonaws.com/dev"
}
func makeAPICall<T: Codable>(path: String, method: String, body: [String: Any]? = nil) async throws -> T {
guard let url = URL(string: baseURL + path) else {
throw APIError.invalidURL
}
var request = URLRequest(url: url)
request.httpMethod = method
if let body = body {
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
}
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
throw APIError.invalidResponse
}
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
}
}
enum APIError: Error {
case invalidURL
case invalidResponse
case decodingError
}
class ProfilesViewModel: ObservableObject {
@MainActor
func fetchProfiles() async {
do {
let profiles: [DecodableProfile] = try await APIGatewayManager.shared.makeAPICall(path: "/profiles", method: "GET")
self.profiles = profiles.map { $0.toProfile() }
self.showToastMessage("Fetched profiles successfully", isSuccess: true)
} catch {
self.showToastMessage("Error fetching profiles: (error.localizedDescription)", isSuccess: false)
}
}
@MainActor
func updateProfile(_ profile: Profile) async {
do {
let updatedProfile: DecodableProfile = try await APIGatewayManager.shared.makeAPICall(
path: "/profiles/(profile.id)",
method: "PUT",
body: profile.toDecodableProfile().dictionary
)
if let index = self.profiles.firstIndex(where: { $0.id == updatedProfile.id }) {
self.profiles[index] = updatedProfile.toProfile()
}
self.showToastMessage("Profile updated successfully", isSuccess: true)
} catch {
self.showToastMessage("Error updating profile: (error.localizedDescription)", isSuccess: false)
}
}
}
extension Encodable {
var dictionary: [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String: Any]
}
}
</code>
class APIGatewayManager {
static let shared = APIGatewayManager()
private let baseURL: String
private init() {
self.baseURL = "https://abc123def.execute-api.us-west-2.amazonaws.com/dev"
}
func makeAPICall<T: Codable>(path: String, method: String, body: [String: Any]? = nil) async throws -> T {
guard let url = URL(string: baseURL + path) else {
throw APIError.invalidURL
}
var request = URLRequest(url: url)
request.httpMethod = method
if let body = body {
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
}
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
throw APIError.invalidResponse
}
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
}
}
enum APIError: Error {
case invalidURL
case invalidResponse
case decodingError
}
class ProfilesViewModel: ObservableObject {
@MainActor
func fetchProfiles() async {
do {
let profiles: [DecodableProfile] = try await APIGatewayManager.shared.makeAPICall(path: "/profiles", method: "GET")
self.profiles = profiles.map { $0.toProfile() }
self.showToastMessage("Fetched profiles successfully", isSuccess: true)
} catch {
self.showToastMessage("Error fetching profiles: (error.localizedDescription)", isSuccess: false)
}
}
@MainActor
func updateProfile(_ profile: Profile) async {
do {
let updatedProfile: DecodableProfile = try await APIGatewayManager.shared.makeAPICall(
path: "/profiles/(profile.id)",
method: "PUT",
body: profile.toDecodableProfile().dictionary
)
if let index = self.profiles.firstIndex(where: { $0.id == updatedProfile.id }) {
self.profiles[index] = updatedProfile.toProfile()
}
self.showToastMessage("Profile updated successfully", isSuccess: true)
} catch {
self.showToastMessage("Error updating profile: (error.localizedDescription)", isSuccess: false)
}
}
}
extension Encodable {
var dictionary: [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String: Any]
}
}
Tried setting up Amplify to work with existing Lambda S3 service through API Gateway/Serverless but got lost very quickly.