Moya: How to validate response with custom rule

Created on 1 Feb 2018  路  4Comments  路  Source: Moya/Moya

Using: Moya 10.0.1

An example of my responses are:

{
  "data": {},
  "meta": {
    "error_code": 10938,
    "error_message": "Something bad happened!"
  }
}

Everytime meta.error_code is filled, I would like to perform custom logic on all or some of the responses, like showing an alert with meta.error_message's value.

As this might happen in all the requests, how and where would I put this logic?

question

Most helpful comment

Sure! Here's how I'm doing with SwiftyJSON:

import Moya
import Result
import SwiftyJSON

class ResponseProcessorPlugin: PluginType {
    func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
        switch(result) {
        case .success(let response):
            // Here I can validate and perform arbitrary logic
            guard let jsonResponse = try? JSON(data: response.data) else { return }
            let meta = jsonResponse["meta"]

            if let errorCode = meta["error"].int {
                let errorMessage = meta["message"].stringValue
                print("Error code: \(errorCode)'. Message: \(errorMessage)")
            }
        case .failure(let error):
            print(error.errorDescription ?? "No description provided")
        }
    }
}

// Here I configure my provider
let provider = MoyaProvider<MyTarget>(plugins: [ResponseProcessorPlugin()])

Hope it helps.
BTW Moya is awesome!

All 4 comments

Well, It seems that this is a job for a PluginType.

I created a implementation of PluginType and processed it inside the didReceive:result:target function.

Worked like a charm!

Is that's the more appropriate way to solve this, this thread can be closed.

Hey @juniorgarcia, that's a good one. In Moya 11 we introduced an enum type for ValidationType (you can check it here). You can specify your own validation for status codes of your response, but it seems like you have these codes in the response body instead. Thus, plugins seems like a pretty good solution. You could share it here so maybe someone else in your position will benefit from this it as well.

Sure! Here's how I'm doing with SwiftyJSON:

import Moya
import Result
import SwiftyJSON

class ResponseProcessorPlugin: PluginType {
    func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
        switch(result) {
        case .success(let response):
            // Here I can validate and perform arbitrary logic
            guard let jsonResponse = try? JSON(data: response.data) else { return }
            let meta = jsonResponse["meta"]

            if let errorCode = meta["error"].int {
                let errorMessage = meta["message"].stringValue
                print("Error code: \(errorCode)'. Message: \(errorMessage)")
            }
        case .failure(let error):
            print(error.errorDescription ?? "No description provided")
        }
    }
}

// Here I configure my provider
let provider = MoyaProvider<MyTarget>(plugins: [ResponseProcessorPlugin()])

Hope it helps.
BTW Moya is awesome!

@juniorgarcia I'm going to close this one as you seem to have resolved the issue. Thank you for posting your solution to potentially help other Moya users.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

holysin picture holysin  路  3Comments

sunshinejr picture sunshinejr  路  3Comments

Tynox picture Tynox  路  3Comments

pedrovereza picture pedrovereza  路  3Comments

hamada147 picture hamada147  路  3Comments