-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decoder for Atlas Functions result #8137
Comments
Hey, we've been chatting with the team on how to approach this. In the meantime, you could implement your own functions client and use the import RealmSwift
import Realm
import SwiftBSON
struct FunctionClient {
let functionsUrl: URL
let user: User
let _decoder = ExtendedJSONDecoder()
let _encoder = ExtendedJSONEncoder()
init(appId: String, app: App, user: User) {
functionsUrl = URL(string: "\(app.configuration.baseURL!)/api/client/v2.0/app/\(appId)/functions/call")!
self.user = user
}
func callFunction<T: Decodable>(_: T.Type, name: String, args: [Encodable]) async throws -> T {
var request = URLRequest(url: functionsUrl)
request.setValue( "Bearer \(user.accessToken!)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let serializedArgs = try args.map {
return try String(decoding: _encoder.encode($0), as: UTF8.self)
}.joined(separator: ",")
let body = "{ \"name\": \"\(name)\", \"arguments\": [\(serializedArgs)] }"
request.httpBody = Data(body.utf8)
let (data, response) = try await URLSession.shared.data(for: request)
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 401 {
try await user.refreshCustomData()
return try await callFunction(T.self, name: name, args: args)
}
}
return try _decoder.decode(T.self, from: data)
}
} And you use it like: // Define your strongly-typed model representing the result
struct FunctionResult: Codable, Equatable {
let result: Int32
}
let functionClient = FunctionClient(appId: "my-app-id", app: app, user: user)
let result = try await functionClient.callFunction(FunctionResult.self, name: "addNumbers", args: [1, 2]) It's not the most elegant solution and the code can certainly be made more swift-y, but I hope it'll unblock you until we have a proper first-party API. |
Nice idea! |
@solkpolk I opened up a draft for you: #8142 import SwiftBSON
private struct Preferences: Codable {
let favoriteColor: String
let apples: Int
}
func testUserCallFunctionAsyncAwaitCodable() async throws {
let user = try await self.app.login(credentials: basicCredentials())
let preferences = try ExtendedJSONDecoder().decode(Preferences.self,
from: try await user.functions.preferences())
XCTAssertEqual(preferences.favoriteColor, "green")
XCTAssertEqual(preferences.apples, 10)
} Using my branch, you should be able to use the normal pathway ( |
Works. Many thanks 🙏 |
Problem
Decoding results from Atlas App Functions. I'm assuming a lot of people using atlas app functions would like this feature
Solution
No response
Alternatives
No response
How important is this improvement for you?
Would be a major improvement
Feature would mainly be used with
Atlas App Services: Auth or Functions etc
The text was updated successfully, but these errors were encountered: