Giter Club home page Giter Club logo

jsonrpckit's Introduction

JSONRPCKit

Build Status Carthage compatible CocoaPods

JSONRPCKit is a type-safe JSON-RPC 2.0 library purely written in Swift.

// Generating request JSON
let batchFactory = BatchFactory(version: "2.0", idGenerator: NumberIdGenerator())
let request = Subtract(minuend: 42, subtrahend: 23)
let batch = batchFactory.create(request)
let encoder = JSONEncoder()
let data = try! encoder.encode(batch)
let jsonString = String(data: data, encoding: .utf8) // {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}

// Parsing response JSON
let responseObject: String = 
	""" 
	{ "jsonrpc": "2.0", "result": 19, "id": 1}
	"""
let responseData = responseObject.data(using: .utf8)!
let response = try! batch.responses(from: responseData)
response // 19 (type of response is inferred from SubtractRequest.Response)

Requirements

  • Swift 5.3 / Xcode 12.2 or later
    • If you use Swift 3.1 (Xcode 8.3), you can use 2.0.3 instead.
  • iOS 12.0 or later
  • macOS 10.10 or later
  • watchOS 2.0 or later
  • tvOS 9.0 or later
  • Linux is also supported

Basic usage

  1. Create Decodable Response type
  2. Define request type
  3. Generate request JSON

Defining request type

First of all, define a request type that conforms to Request.

struct Subtract: JSONRPCKit.Request {
    typealias Response = Int

    let minuend: Int
    let subtrahend: Int

    var method: String {
        return "subtract"
    }

    var parameters: Encodable? {
        return [minuend, subtrahend]
    }
}
Tip

If your parameters are not the same type

    var parameters: Encodable? {
        return [42, "Answer to the question"]
    }

you can use the included type erasure wrapper AnyEncodable:

    var parameters: Encodable? {
        return [AnyEncodable(42), AnyEncodable("Answer to the question")]
    }

Generating request JSON

To generate request JSON, pass Request instances to BatchFactory instance, which has common JSON-RPC version and identifier generator. When BatchFactory instance receives request(s), it generates identifier(s) for the request(s) and request JSON by combining id, version, method and parameters.

let batchFactory = BatchFactory(version: "2.0", idGenerator: NumberIdGenerator())
let request1 = Subtract(minuend: 42, subtrahend: 23)
let request2 = Subtract(minuend: 23, subtrahend: 42)
let batch = batchFactory.create(request1, request2)

The request JSON can be generated by JSONEncoder.

let encoder = JSONEncoder()
let data = try! encoder.encode(batch)
let jsonString = String(data: data, encoding: .utf8) 

jsonString looks like below:

[
  {
    "method" : "subtract",
    "jsonrpc" : "2.0",
    "id" : 1,
    "params" : [
      42,
      23
    ]
  },
  {
    "method" : "subtract",
    "jsonrpc" : "2.0",
    "id" : 2,
    "params" : [
      23,
      42
    ]
  }
]

Parsing response JSON

Suppose that following JSON is returned from server:

[
  {
    "result" : 19,
    "jsonrpc" : "2.0",
    "id" : 1,
    "status" : 0
  },
  {
    "result" : -19,
    "jsonrpc" : "2.0",
    "id" : 2,
    "status" : 0
  }
]

To parse response object, execute responses(from:) of Batch instance. When responses(from:) is called, Batch finds corresponding response object by comparing request id and response id. After it find the response object, it executes responses(from:) of Response to get Request.Response from the response object.

let responseStr: String = ...
let responseData = responseObject.data(using: .utf8)!

let (response1, response2) = try! batch.responses(from: responseData)
print(response1) // 19
print(response2) // -19

JSON-RPC over HTTP by APIKit

APIKit is a type-safe networking abstraction layer.

Defining HTTP request type

APIKit also has RequestType that represents HTTP request.

import APIKit

struct MyServiceRequest<Batch: JSONRPCKit.Batch>: APIKit.Request {
    let batch: Batch

    typealias Response = Batch.Responses

    var baseURL: URL {
        return URL(string: "https://api.example.com/")!
    }

    var method: HTTPMethod {
        return .post
    }

    var path: String {
        return "/"
    }

    var parameters: Any? {
        let encoder = JSONEncoder()
        guard let data = try? encoder.encode(batch) else {
            return nil
        }
        return try? JSONSerialization.jsonObject(with: data, options: [])
    }

    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
        let jsonData = try JSONSerialization.data(withJSONObject:object)
        return try batch.responses(from: jsonData)
    }
}

Sending HTTP/HTTPS request

let batchFactory = BatchFactory(version: "2.0", idGenerator: NumberIdGenerator())
let request1 = Subtract(minuend: 42, subtrahend: 23)
let request2 = Subtract(minuend: 23, subtrahend: 42)
let batch = batchFactory.create(request1, request2)
let httpRequest = MyServiceRequest(batch: batch)

Session.sendRequest(httpRequest) { result in
    switch result {
    case .Success(let response1, let response2):
        print(response1.count) // CountCharactersResponse
        print(response2.count) // CountCharactersResponse

    case .Failure(let error):
        print(error)
    }
}

License

JSONRPCKit is released under the MIT License.

jsonrpckit's People

Contributors

fxwx23 avatar ishkawa avatar ollitapa avatar sajjon avatar samukei avatar

Stargazers

 avatar

Watchers

 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.