Giter Site home page Giter Site logo

bodybuilder's Introduction

Build Status codecov

BodyBuilder

BodyBuilder is a small framework for working with URLRequest HTTP body and print its human-readable description. Become stronger with BodyBuilder! ๐Ÿ’ช

What problems does this framework solve?

  1. Creating Headers with names, values and attributes minimizing the risk of misspelling.
  2. Viewing request body in a readable format.
  3. Respecting common and frequently used predefined header names/values/attributes but still having ability to set your very custom data.

In details: Creating and using headers

The header is a line with name, value and list of parameters. For some of header names values are predefined.

Header Names

Using

Header.Name is probably most frequently class using in this framework. The most frequently used frameworks are predefined.

// Create you header by passing an static variable
let authHeader = HeaderField.init(.authorization, value: .with("Basic 123456789"))

Custom

Moreover, you can add your very custom headers very easy.

// Add your custom header in your product by making extension of Header.Name:
extension Header.Name {
    public static let myHeaderField = HeaderField.Name.init("My-Header-Field")
}

// Use it in code like other predefined headers!
let header = HeaderField.init(.myHeaderField, value: .with("My value"))

Header Values

Using

The trivial way to pass value is to init Header.Value with rawValue:

let header = HeaderField.init(.accept, value: HeaderField.Value.init("text/plain"))

Or more shortly:

let header1 = HeaderField.init(.accept, value: .init("text/plain"))

// '.with' is just a static method which accept strings (while init accepts any HeaderValueRepresentable conforming types)
let header2 = HeaderField.init(.accept, value: .with("text/plain"))

Custom

Header.Value can hold any value which is conforms to HeaderValueRepresentable (returns headerValueString)

public enum Direction: String, HeaderValueRepresentable {
    case forward = "fwd"
    case left = "lft"
    case right = "rgh"

    public var headerValueString: String {
        return self.rawValue
    }
}

/// Direction: fwd
let header = HeaderField.init(name: "Direction", value: .init(Direction.forward))

Predefined

Some values are predefined. Depends on using, they can be option sets:

let header = HeaderField.init(.allow, value: .allow([.get, .head]))

Enums:

let header = HeaderField.init(.cacheControl, value: .cacheControl(.rules(.maxAge(seconds: 14),
                                                                         .maxStale(seconds: nil),
                                                                         .mustRevalidate)))

Or anything else as long as it conforms HeaderValueRepresentable

Attributes

Attributes can be varied in a very wide range, but you still have a couple of helping abilities like contentDisposition which is frequently used to put some file (i. e. image) into a body.

// name is String, filename is String?
// This method respects optional filename, so you can pass nullability testing which would be required for creating array.
let header = HeaderField.init(.contentDisposition,
                                       value: .contentDisposition(.formData),
                                       attributes: .contentDisposition(.name(name, filename: filename)))

In Details: Readability

In URLRequest httpBody is just a Data and in most cases, it's just a utf-8 encoded string, so you can decode it and read. But when you adding some file data into body โ€“ it can become undecodable or, at least, hard to read. With BodyBuilder you can easily put data into a body and looks to body's description and it will look nice

var body = Body()
var dispositionHeader = HeaderField.init(.contentDisposition,
                                             value: .contentDisposition(.formData))
dispositionHeader.attributes = .contentDisposition(name: "\"File\"", filename: "\"file1.zip\"")
body.append(byHeaderField: dispositionHeader)
body.append(byHeaderField: .init(.contentType, value: .with("application/zip")), lineBreaks: 2)


/*
Content-Disposition: form-data; name="File"; filename="file1.zip"
Content-Type: application/zip

*/
print(body)

let fileUrl = Bundle(for: type(of: self)).url(forResource: "BodyBuilder.h", withExtension: "zip")!
let file = try! Data.init(contentsOf: fileUrl)
body.append(by: file)
/*
Content-Disposition: form-data; name="File"; filename="file1.zip"
Content-Type: application/zip

<Bytes (length: 431 bytes)>
*/
print(body)

Custom body items

You can declare your custom items by adopting it to conform BodyItemRepresentable protocol:

public struct File: BodyItemRepresentable {
    var filename: String
    var data: Data
    var url: URL

    public init(url: URL) {
        self.url = url
        self.filename = url.lastPathComponent
        self.data = try! Data.init(contentsOf: url)
    }

    public var httpRequestBodyData: Data {
        return data
    }

    public var httpRequestBodyDescription: String {
        return "File data from \(url)"
    }
}


let fileUrl = Bundle(for: type(of: self)).url(forResource: "BodyBuilder.h", withExtension: "zip")!
let file = File.init(url: fileUrl)
var body = Body()
body.append(by: file)

/*
File data from <path...>/BodyBuilder.h.zip
*/
print(body)
    

bodybuilder's People

Contributors

vladlex avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.