Skip to content

Instantly share code, notes, and snippets.

@vzsg
Last active December 10, 2021 14:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vzsg/60727cfa2d47462f385ea84d58024ff3 to your computer and use it in GitHub Desktop.
Save vzsg/60727cfa2d47462f385ea84d58024ff3 to your computer and use it in GitHub Desktop.
App Store Rating Lookup for Vapor 3
import Foundation
import Vapor
struct AppInfo: Codable {
let averageUserRating: Double
let userRatingCount: Int
}
enum AppleAppLookupError: Error {
case notFound
}
final class AppleAppLookup: ServiceType {
private let client: Client
init(client: Client) {
self.client = client
}
static func makeService(for container: Container) throws -> AppleAppLookup {
let client = try container.client()
return AppleAppLookup(client: client)
}
func getAppInfo(_ itunesID: String) -> Future<AppInfo> {
var components = URLComponents(string: "https://itunes.apple.com/gb/lookup")!
components.queryItems = [URLQueryItem(name: "id", value: itunesID)]
return client.get(components.url!).flatMap { resp -> Future<AppInfoResponse> in
// Override Content-Type returned from the server with application/json
// so Vapor's Content decoding does not throw up.
resp.http.contentType = .json
return try resp.content.decode(AppInfoResponse.self)
}.map {
guard let info = $0.results.first else {
throw AppleAppLookupError.notFound
}
return info
}
}
}
private struct AppInfoResponse: Decodable {
let results: [AppInfo]
}
import Vapor
public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws {
// ... other configuration omitted for brevity ...
// Register AppleAppLookup service
services.register(AppleAppLookup.self)
}
import Vapor
public func routes(_ router: Router) throws {
// Example route that uses AppleAppLookup
router.get("apple", String.parameter) { req -> Future<String> in
let itunesID: String = try req.parameters.next()
let lookup = try req.make(AppleAppLookup.self)
return lookup.getAppInfo(itunesID)
.map { "Rating: \($0.averageUserRating) out of \($0.userRatingCount) review\($0.userRatingCount == 1 ? "" : "s")" }
}
}
curl localhost:8080/apple/1229016807
Rating: 5.0 out of 34953 reviews
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment