Skip to content
/ Janet Public

A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveraging the power of async/await.

License

Notifications You must be signed in to change notification settings

nholloh/Janet

Repository files navigation

🤵🏽‍♀️ Janet

— Just another networking kit —

A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveraging the power of async/await.

    // Defines what the service's endpoint looks like.
    struct GetUsersRequest: NetworkRequestWithResponse {
        // The decodable response type we expect.
        typealias ResponseType = GetUsersResponse

        // The HTTP method used.
        let method: HTTPMethod = .get
        
        // The URL.
        let endpoint: URL = .init(string: "https://reqres.in/api/users")!
    }
    
    func getUsers(page: Int) throws async -> GetUsersResponse {
        // Create an instance of the request.
        let request = GetUsersRequest()
        
        // Create a network manager. You may use an shared instance.
        let networkManager = NetworkManager()
        
        // Send the request.
        return try await networkManager.send(request: request)
    }

Features

The following features have been implemented or are planned for implementation.

If you would like to raise a feature request, please refer to the contribution section first.

Installation

Swift Package Manager

Please add the following line to the dependencies array in your Package.swift file:

    .package(url: "https://github.com/nholloh/Janet", from: "0.1.0")

Supported Platforms

  • iOS 13+
  • macOS 10.15+
  • watchOS 6+
  • tvOS 13+

Prior to Xcode 13.2, concurrency features will only work for iOS 15, macOS 11, watchOS 8 and tvOS 15. Linux and Windows are not supported. Please upvote the respective issue, if you'd like to see support.

Usage

First, find out what the traits of the endpoint you want to connect to are. Then, use any combination of the protocols below to define your service configuration struct:

Trait Description Protocol
Has query parameters Used when your request needs to append query parameters to the URL. NetworkRequestWithQuery
Has request body Used when your request has a body. NetworkRequestWithBody
Expects response body Used when you expect a decodable response. NetworkRequestWithResponse

If none of the above applies, you may use the default NetworkRequest protocol.

Then, create your request configuration. Here are some examples:

Service with response, which has no request body or request parameters:

    struct GetUsersRequest: NetworkRequestWithResponse {
        // The decodable response type we expect.
        typealias ResponseType = GetUsersResponse

        // The HTTP method used.
        let method: HTTPMethod = .get
        
        // The URL.
        let endpoint: URL = .init(string: "https://reqres.in/api/users")!
    }

Service with query parameters and response:

    struct GetUsersRequestPaged: NetworkRequestWithQuery, NetworkRequestWithResponse {
        // The query type to be encoded into the URL.
        struct Query: Encodable {
            let page: Int
        }

        struct ResponseType: Decodable {
            let page: Int
            let total: Int
        }

        let method: HTTPMethod = .get
        
        // An instance of above query type
        let query: Encodable
        let endpoint: URL = .init(string: "https://reqres.in/api/users")!
    }

Service with request body, without response:

    struct CreateUserRequest: NetworkRequestWithBody {
        
        // The body to be sent with the HTTP request.
        struct BodyType: Encodable {
            let name: String
            let job: String
        }

        let method: HTTPMethod = .post
        let body: BodyType
        let endpoint: URL = .init(string: "https://reqres.in/api/users")!
    }

Then, create an instance of your new request configuration and use it with an instance of NetworkManager to send your request:

    func getUsers(page: Int) throws async -> GetUsersResponse {
        // Create an instance of the request.
        let request = GetUsersRequest()
        
        // Create a network manager. You may use a shared instance.
        let networkManager = NetworkManager()
        
        // Send the request.
        return try await networkManager.send(request: request)
    }

For detailed documentation, please check the Features.

What does Janet stand for?

Its an acronym, which stands for:

J Just

A another

NET Network (library)

Also, its a reference to an incredibly helpful and empathetic AI from the series The Good Place. If you haven't seen it, you should definitely check it out!

Contributing

For contributions, please consider the following scenarios:

You find a bug

Please raise an issue and describe the bug you found. Feel free to fork and fix the bug, then raise a pull request with us. A collaborator of Janet will review it shortly and provide feedback.

You have a feature request

In case you have a feature request, please raise an issue with the feature request. We will assess importance of features based on the number of upvotes of said issue. If you already have a concrete idea how this feature may work, you may of course fork and make the necessary changes. Please remember to update the documentation!

IDE setup

There's no special setup required (as of now)! Just check out the code and start tinkering.

About

A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveraging the power of async/await.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages