All Projects → freshOS → Networking

freshOS / Networking

Licence: mit
⚡️ Elegantly connect to a REST JSON Api. URLSession + Combine + Decodable + Generics = <3

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Networking

Ws
⚠️ Deprecated - (in favour of Networking) ☁️ Elegantly connect to a JSON api. (Alamofire + Promises + JSON Parsing)
Stars: ✭ 352 (-29.46%)
Mutual labels:  rest-api, rest, json, networking, httpclient
Restclient
🦄 Simple HTTP and REST client for Unity based on Promises, also supports Callbacks! 🎮
Stars: ✭ 675 (+35.27%)
Mutual labels:  rest-api, rest, json, httpclient
Spyke
Interact with REST services in an ActiveRecord-like manner
Stars: ✭ 591 (+18.44%)
Mutual labels:  api, rest-api, rest, json
Http Fake Backend
Build a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 253 (-49.3%)
Mutual labels:  api, rest-api, rest, json
Json Serverless
Transform a JSON file into a serverless REST API in AWS cloud
Stars: ✭ 108 (-78.36%)
Mutual labels:  api, rest-api, rest, json
Generator Http Fake Backend
Yeoman generator for building a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 49 (-90.18%)
Mutual labels:  api, rest-api, rest, json
Httpie
As easy as /aitch-tee-tee-pie/ 🥧 Modern, user-friendly command-line HTTP client for the API era. JSON support, colors, sessions, downloads, plugins & more. https://twitter.com/httpie
Stars: ✭ 53,052 (+10531.66%)
Mutual labels:  api, rest-api, rest, json
Json Api Dart
JSON:API client for Dart/Flutter
Stars: ✭ 53 (-89.38%)
Mutual labels:  api, rest-api, rest, json
Api Client Generator
Angular REST API client generator from Swagger YAML or JSON file with camel case settigs
Stars: ✭ 92 (-81.56%)
Mutual labels:  api, rest, json, httpclient
Grafanajsondatasource
Grafana datasource to load JSON data over your arbitrary HTTP backend
Stars: ✭ 146 (-70.74%)
Mutual labels:  api, rest-api, rest, json
Flask Restplus
Fully featured framework for fast, easy and documented API development with Flask
Stars: ✭ 2,585 (+418.04%)
Mutual labels:  api, rest, json
Datoji
A tiny JSON storage service. Create, Read, Update, Delete and Search JSON data.
Stars: ✭ 222 (-55.51%)
Mutual labels:  api, rest-api, json
Bookmarks.dev
Bookmarks and Code Snippets Manager for Developers & Co
Stars: ✭ 218 (-56.31%)
Mutual labels:  api, rest-api, rest
Symfony Flex Backend
Symfony Flex REST API template project
Stars: ✭ 214 (-57.11%)
Mutual labels:  api, rest-api, rest
Mockoon
Mockoon is the easiest and quickest way to run mock APIs locally. No remote deployment, no account required, open source.
Stars: ✭ 3,448 (+590.98%)
Mutual labels:  api, rest-api, rest
Horaires Ratp Api
Webservice pour les horaires et trafic RATP en temps réel
Stars: ✭ 232 (-53.51%)
Mutual labels:  api, rest, json
Wp Rest Api Cache
Enable caching for WordPress REST API and increase speed of your application
Stars: ✭ 239 (-52.1%)
Mutual labels:  api, rest-api, rest
Magic
Create your .Net Core/Angular/Database CRUD Web apps by simply clicking a button
Stars: ✭ 214 (-57.11%)
Mutual labels:  api, rest-api, rest
Vulcain
Fast and idiomatic client-driven REST APIs.
Stars: ✭ 3,190 (+539.28%)
Mutual labels:  api, rest-api, rest
Imbo
Imbo is an image "server" that can be used to add/get/delete images using a RESTful interface.
Stars: ✭ 312 (-37.47%)
Mutual labels:  rest-api, rest, json

Networking

Networking

Language: Swift 5 Platform: iOS 13+ SPM compatible License: MIT Build Status codebeat badge Release version

Networking brings together URLSession, Combine, Decodable and Generics to make connecting to a JSON api a breeze.

struct Api: NetworkingService {

    let network = NetworkingClient(baseURL: "https://jsonplaceholder.typicode.com")

    func fetchPost() -> AnyPublisher<Post, Error> {
        get("/posts/1")
    }
}

Later...

let api = Api()
api.fetchPost().sink(receiveCompletion: { _ in }) { post in
    // Get back some post \o/
}.store(in: &cancellables)

How

By providing a lightweight client that automates boilerplate code everyone has to write.
By exposing a delightfully simple api to get the job done simply, clearly, quickly.
Getting swift models from a JSON api is now a problem of the past

URLSession + Combine + Generics + Protocols = Networking.

What

  • [x] Build a concise Api
  • [x] Automatically map your models
  • [x] Uses latest Apple's Combine
  • [x] Compatible with native Codable and any JSON Parser
  • [x] Embarks a built-in network logger
  • [x] Pure Swift, simple, lightweight & 0 dependencies

Welcome the future. Bye ws , Hello Networking.

Networking is the next generation of the ws project. The improvements are: Using Combine native Apple's framework over Then Promise Library, removing Arrow dependency to favour Codable (Arrow can still be adapted easily though) and removing the Alamofire dependency in favour of a simpler purely native URLSession implementation.
In essence, less dependencies and more native stuff.

Try it!

Networking is part of freshOS iOS toolset. Try it in an example App ! Download Starter Project

Getting Started

Install it

Networking is installed via the official Swift Package Manager.

Select Xcode>File> Swift Packages>Add Package Dependency...
and add https://github.com/freshOS/Networking.

Create a Client

let client = NetworkingClient(baseURL: "https://jsonplaceholder.typicode.com")

Make your first call

Use get, post, put & delete methods on the client to make calls.

client.get("/posts/1").sink(receiveCompletion: { _ in }) { (data:Data) in
    // data
}.store(in: &cancellables)

Get the type you want back

Networking recognizes the type you want back via type inference. Types supported are Void, Data, Any(JSON), NetworkingJSONDecodable(Your Model) & [NetworkingJSONDecodable]

This enables keeping a simple api while supporting many types :

let voidPublisher: AnyPublisher<Void, Error> = client.get("")
let dataPublisher: AnyPublisher<Data, Error> = client.get("")
let jsonPublisher: AnyPublisher<Any, Error> = client.get("")
let postPublisher: AnyPublisher<Post, Error> = client.get("")
let postsPublisher: AnyPublisher<[Post], Error> = client.get("")

Pass params

Simply pass a [String: CustomStringConvertible] dictionary to the params parameter.

client.postsPublisher("/posts/1", params: ["optin" : true ])
    .sink(receiveCompletion: { _ in }) { (data:Data) in
      //  response
    }.store(in: &cancellables)

Upload multipart data

For multipart calls (post/put), just pass a MultipartData struct to the multipartData parameter.

let params: [String: CustomStringConvertible] = [ "type_resource_id": 1, "title": photo.title]
let multipartData = MultipartData(name: "file",
                                  fileData: photo.data,
                                  fileName: "photo.jpg",
                                   mimeType: "image/jpeg")
client.post("/photos/upload",
            params: params,
            multipartData: multipartData).sink(receiveCompletion: { _ in }) { (data:Data?, progress: Progress) in
                if let data = data {
                    print("upload is complete : \(data)")
                } else {
                    print("progress: \(progress)")
                }
}.store(in: &cancellables)

Add Headers

Headers are added via the headers property on the client.

client.headers["Authorization"] = "[mytoken]"

Add Timeout

Timeout (TimeInterval in seconds) is added via the optional timeout property on the client.

let client = NetworkingClient(baseURL: "https://jsonplaceholder.typicode.com", timeout: 15)

Alternatively,

client.timeout = 15 

Cancel a request

Since Networking uses the Combine framework. You just have to cancel the AnyCancellable returned by the sink call.

var cancellable = client.get("/posts/1").sink(receiveCompletion: { _ in }) { (json:Any) in
  print(json)
}

Later ...

cancellable.cancel()

Log Network calls

3 log levels are supported: off, info, debug

client.logLevels = .debug

Handling errors

Errors can be handled on a Publisher, such as:

client.get("/posts/1").sink(receiveCompletion: { completion in
switch completion {
case .finished:
    break
case .failure(let error):
    switch error {
    case let decodingError DecodingError:
        // handle JSON decoding errors
    case let networkingError NetworkingError:
        // handle NetworkingError
        // print(networkingError.status)
        // print(networkingError.code)
    default:
        // handle other error types
        print("\(error.localizedDescription)")
    }
}   
}) { (response: Post) in
    // handle the response
}.store(in: &cancellables)

Support JSON-to-Model parsing.

For a model to be parsable by Networking, it needs to conform to the NetworkingJSONDecodable protocol.

For example if you are using Arrow for JSON Parsing. Supporting a Post model will look like this:

extension Post: NetworkingJSONDecodable {
    static func decode(_ json: Any) throws -> Post {
        var t = Post()
        if let arrowJSON = JSON(json) {
            t.deserialize(arrowJSON)
        }
        return t
    }
}

Instead of doing it every models, you can actually do it once for all with a clever extension 🤓.

extension ArrowParsable where Self: NetworkingJSONDecodable {

    public static func decode(_ json: Any) throws -> Self {
        var t: Self = Self()
        if let arrowJSON = JSON(json) {
            t.deserialize(arrowJSON)
        }
        return t
    }
}

extension User: NetworkingJSONDecodable { }
extension Photo: NetworkingJSONDecodable { }
extension Video: NetworkingJSONDecodable { }
// etc.

This default extension is already provided for the native Decodable type. So if your models are Decodable then you just have to add:

extension Mymodel: NetworkingJSONDecodable { }

You can support any JSON parsing by replacing the code above with whatever JSON parsing library you are using \o/ !

// TODO Document network.defaultCollectionParsingKeyPath = "collection" Clean Api

Design a clean api

In order to write a concise api, Networking provides the NetworkingService protocol. This will forward your calls to the underlying client so that your only have to write get("/route") instead of network.get("/route"), while this is overkill for tiny apis, it definitely keep things concise when working with massive apis.

Given an Article model

struct Article: Codable {
    let id: String
    let title: String
    let content: String
}

Make your Article NetworkingJSONDecodable, this is a one liner since Codable is supported by default.

extension Article: NetworkingJSONDecodable {}

Here is what a typical CRUD api would look like :

struct CRUDApi: NetworkingService {

    var network = NetworkingClient(baseURL: "https://my-api.com")

    // Create
    func create(article a: Article) -> AnyPublisher<Article, Error> {
        post("/articles", params: ["title" : a.title, "content" : a.content])
    }

    // Read
    func fetch(article a: Article) -> AnyPublisher<Article, Error> {
        get("/articles/\(a.id)")
    }

    // Update
    func update(article a: Article) -> AnyPublisher<Article, Error> {
        put("/articles/\(a.id)", params: ["title" : a.title, "content" : a.content])
    }

    // Delete
    func delete(article a: Article) -> AnyPublisher<Void, Error> {
        delete("/articles/\(a.id)")
    }

    // List
    func articles() -> AnyPublisher<[Article], Error> {
        get("/articles")
    }
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].