From b5992f090b0f4ee5a017ec1468b19765762891e7 Mon Sep 17 00:00:00 2001 From: Tibor Bodecs Date: Fri, 11 Mar 2022 13:43:21 +0100 Subject: [PATCH] basic readme --- README.md | 205 +++++++----------------------------------------------- 1 file changed, 26 insertions(+), 179 deletions(-) diff --git a/README.md b/README.md index 09c4257..2b289cf 100644 --- a/README.md +++ b/README.md @@ -1,218 +1,65 @@ # SwiftHttp -An awesome Swift HTTP library to rapidly setup the communication layer with API endpoints. - -```swift -import SwiftHttp - -print(html) -``` - +An awesome Swift HTTP library to rapidly create communication layers with API endpoints. ## Install You can simply use `SwiftHtml` as a dependency via the Swift Package Manager: ```swift -.package(url: "https://github.com/binarybirds/swift-html", from: "1.6.0"), +.package(url: "https://github.com/binarybirds/swift-http", from: "1.0.0"), ``` -Add the `SwiftHtml` product from the `swift-html` package as a dependency to your target: +Add the `SwiftHttp` product from the `swift-http` package as a dependency to your target: ```swift -.product(name: "SwiftHtml", package: "swift-html"), +.product(name: "SwiftHttp", package: "swift-http"), ``` Import the framework: ```swift -import SwiftHtml +import SwiftHttp ``` That's it. -## Creating custom tags - -You can define your own custom tags by subclassing the `Tag` or `EmptyTag` class. - -You can follow the same pattern if you take a look at the core tags. - -```swift -open class Div: Tag { - -} - -//
- standard tag - -open class Br: EmptyTag { - -} -//
- no closing tag - -``` - -By default the name of the tag is automatically derived from the class name (lowercased), but you can also create your own tag type & name by overriding the `createNode()` class function. - -```swift -open class LastBuildDate: Tag { - - open override class func createNode() -> Node { - Node(type: .standard, name: "lastBuildDate") - } -} - -// - standard tag with custom name -``` - -It is also possible to create tags with altered content or default attributes. - -```swift -open class Description: Tag { - - public init(_ contents: String) { - super.init() - setContents("") - } -} -// - content wrapped in CDATA - -open class Rss: Tag { - - public init(@TagBuilder _ builder: () -> [Tag]) { - super.init(builder()) - setAttributes([ - .init(key: "version", value: "2.0"), - ]) - } -} -// ... - tag with a default attribute -``` - -## Attribute management +## Basic usage -You can set, add or delete the attributes of a given tag. +It is really easy to setup a communication layer with an API endpoint. ```swift -Leaf("example") - // set (override) the current attributes - .setAttributes([ - .init(key: "a", value: "foo"), - .init(key: "b", value: "bar"), - .init(key: "c", value: "baz"), - ]) - // add a new attribute using a key & value - .attribute("foo", "example") - // add a new flag attribute (without a value) - .flagAttribute("bar") - // delete an attribute by using a key - .deleteAttribute("b") - -// -``` - -You can also manage the class atrribute through helper methods. - -```swift -Span("foo") - // set (override) class values - .class("a", "b", "c") - // add new class values - .class(add: ["d", "e", "f"]) - // add new class value if the condition is true - .class(add: "b", true) - /// remove multiple class values - .class(remove: ["b", "c", "d"]) - /// remove a class value if the condition is true - .class(remove: "e", true) - -// -``` - -You can create your own attribute modifier via an extension. - -```swift -public extension Guid { - - func isPermalink(_ value: Bool = true) -> Self { - attribute("isPermalink", String(value)) - } -} -``` - -There are other built-in type-safe attribute modifiers available on tags. - - -## Composing tags - -You can come up with your own `Tag` composition system by introducing a new protocol. - -```swift -protocol TagRepresentable { - - func build() -> Tag -} - -struct ListComponent: TagRepresentable { +import SwiftHttp - let items: [String] - - init(_ items: [String]) { - self.items = items - } - - @TagBuilder - func build() -> Tag { - Ul { - items.map { Li($0) } - } - } +struct Todo: Codable { + let id: Int + let title: String + let completed: Bool } -let tag = ListComponent(["a", "b", "c"]).build() -``` - -This way it is also possible to extend the `TagBuilder` to support the new protocol. +struct TodoApi: HttpCodablePipelineCollection { -```swift -extension TagBuilder { + let client: HttpClient = UrlSessionHttpClient(log: true) + let apiBaseUrl = HttpUrl(host: "jsonplaceholder.typicode.com") - static func buildExpression(_ expression: TagRepresentable) -> Tag { - expression.build() - } - static func buildExpression(_ expression: TagRepresentable) -> [Tag] { - [expression.build()] - } - - static func buildExpression(_ expression: [TagRepresentable]) -> [Tag] { - expression.map { $0.build() } - } - - static func buildExpression(_ expression: [TagRepresentable]) -> Tag { - GroupTag { - expression.map { $0.build() } - } - } + func list() async throws -> [Todo] { + try await decodableRequest(executor: client.dataTask, + url: apiBaseUrl.path("todos"), + method: .get) + } } -``` -Sometimes you'll need extra parameters for the build function, so you have to call the build method by hand. +// api usage +let todos = try await api.list() -In those cases it is recommended to introduce a `render` function instead of using build. +// curl log +// curl "https://jsonplaceholder.typicode.com/todos/" -```swift - -let tag = WebIndexTemplate(ctx) { - ListComponent(["a", "b", "c"]) - .render(req) -} -.render(req) ``` -If you want to create a lightweight template engine for the [Vapor](https://vapor.codes/) web framework using SwiftHtml, you can see a working example inside the [Feather CMS core](https://github.com/FeatherCMS/feather-core) repository. - +The HttpClient provides the executors to perform data, download or upload tasks. -## Credits & references +You can create decodable, encodable, codable or raw request when using a codable pipeline collection. -- [HTML Reference](https://www.w3schools.com/tags/default.asp)