|
| 1 | +//===----------------------------------------------------------------------===// |
| 2 | +// |
| 3 | +// This source file is part of the AsyncHTTPClient open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2022 Apple Inc. and the AsyncHTTPClient project authors |
| 6 | +// Licensed under Apache License v2.0 |
| 7 | +// |
| 8 | +// See LICENSE.txt for license information |
| 9 | +// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors |
| 10 | +// |
| 11 | +// SPDX-License-Identifier: Apache-2.0 |
| 12 | +// |
| 13 | +//===----------------------------------------------------------------------===// |
| 14 | + |
| 15 | +import AsyncHTTPClient |
| 16 | +import Foundation |
| 17 | +import NIOCore |
| 18 | +import NIOFoundationCompat |
| 19 | + |
| 20 | +struct Comic: Codable{ |
| 21 | + var num: Int |
| 22 | + var title: String |
| 23 | + var day: String |
| 24 | + var month: String |
| 25 | + var year: String |
| 26 | + var img: String |
| 27 | + var alt: String |
| 28 | + var news: String |
| 29 | + var link: String |
| 30 | + var transcript: String |
| 31 | +} |
| 32 | + |
| 33 | +@main |
| 34 | +struct JSON { |
| 35 | + |
| 36 | + static func main() async throws { |
| 37 | + try await getJSON() |
| 38 | + try await postJSON() |
| 39 | + } |
| 40 | + |
| 41 | + static func getJSON() async throws { |
| 42 | + let httpClient = HTTPClient(eventLoopGroupProvider: .singleton) |
| 43 | + do { |
| 44 | + let request = HTTPClientRequest(url: "https://xkcd.com/info.0.json") |
| 45 | + let response = try await httpClient.execute(request, timeout: .seconds(30)) |
| 46 | + print("HTTP head", response) |
| 47 | + let body = try await response.body.collect(upTo: 1024 * 1024) // 1 MB |
| 48 | + // we use an overload defined in `NIOFoundationCompat` for `decode(_:from:)` to |
| 49 | + // efficiently decode from a `ByteBuffer` |
| 50 | + let comic = try JSONDecoder().decode(Comic.self, from: body) |
| 51 | + dump(comic) |
| 52 | + } catch { |
| 53 | + print("request failed:", error) |
| 54 | + } |
| 55 | + // it is important to shutdown the httpClient after all requests are done, even if one failed |
| 56 | + try await httpClient.shutdown() |
| 57 | + } |
| 58 | + |
| 59 | + static func postJSON() async throws { |
| 60 | + let httpClient = HTTPClient(eventLoopGroupProvider: .singleton) |
| 61 | + |
| 62 | + let comic: Comic = Comic( |
| 63 | + num: 0, |
| 64 | + title: "Adventures of Super Sally", |
| 65 | + day: "17", |
| 66 | + month: "4", |
| 67 | + year: "2025", |
| 68 | + img: "https://www.w3.org/Icons/w3c_main.png", |
| 69 | + alt: "Adventures of Super Sally, a super hero with many powers", |
| 70 | + news: "Today we learn about super heroes!", |
| 71 | + link: "http://comics.com/super-sally", |
| 72 | + transcript: "Once upon a time, there was a super hero named Super Sally. She had many powers and was a hero to many." |
| 73 | + ) |
| 74 | + |
| 75 | + do { |
| 76 | + var request = HTTPClientRequest(url: "https://httpbin.org/post") |
| 77 | + request.headers.add(name: "Content-Type", value: "application/json") |
| 78 | + request.headers.add(name: "Accept", value: "application/json") |
| 79 | + request.method = .POST |
| 80 | + |
| 81 | + let jsonData = try JSONEncoder().encode(comic) |
| 82 | + request.body = .bytes(jsonData) |
| 83 | + |
| 84 | + let response = try await httpClient.execute(request, timeout: .seconds(30)) |
| 85 | + let responseBody = try await response.body.collect(upTo: 1024 * 1024) // 1 MB |
| 86 | + // we use an overload defined in `NIOFoundationCompat` for `decode(_:from:)` to |
| 87 | + // efficiently decode from a `ByteBuffer` |
| 88 | + |
| 89 | + // httpbin.org returns a JSON response with what we sent over the HTTP POST request, |
| 90 | + // the json should be identical |
| 91 | + let returnedComic = try JSONDecoder().decode(Comic.self, from: responseBody) |
| 92 | + assert(comic.title == returnedComic.title) |
| 93 | + assert(comic.img == returnedComic.img) |
| 94 | + assert(comic.alt == returnedComic.alt) |
| 95 | + assert(comic.day == returnedComic.day) |
| 96 | + assert(comic.month == returnedComic.month) |
| 97 | + assert(comic.year == returnedComic.year) |
| 98 | + assert(comic.num == returnedComic.num) |
| 99 | + assert(comic.transcript == returnedComic.transcript) |
| 100 | + assert(comic.news == returnedComic.news) |
| 101 | + assert(comic.link == returnedComic.link) |
| 102 | + dump(returnedComic) |
| 103 | + } catch { |
| 104 | + print("request failed:", error) |
| 105 | + } |
| 106 | + // it is important to shutdown the httpClient after all requests are done, even if one failed |
| 107 | + try await httpClient.shutdown() |
| 108 | + } |
| 109 | +} |
0 commit comments