CodingAleCR / http_interceptor

A lightweight, simple plugin that allows you to intercept request and response objects and modify them if desired.
MIT License
133 stars 67 forks source link

Exclude specific calls from being intercepted/retried -- HeaderSanitizerContract proposal #112

Closed fnicastri closed 1 year ago

fnicastri commented 2 years ago

Is your feature request related to a problem? Please describe. Looking for a way to exclude interceptors and/or the retry policy I ended up using some custom headers (mainly necessary for the retry policy) Es: DO_NOT_REPLY or UNAUTHENTICATED But using them on a Flutter Web project ended up giving some CORS errors due to these custom headers.

Describe the solution you'd like Added a HeaderSanitizerContract to remove custom utility headers before making the request

Describe alternatives you've considered Another approach could be to add specific arguments to every method to exclude the specific call from being retried/intercepted

@CodingAleCR are you interested in a pull request?

https://github.com/fnicastri/http_interceptor/tree/main

Thanks, Francesco

fnicastri commented 2 years ago

nothing? @CodingAleCR

CodingAleCR commented 2 years ago

Hey, thanks for opening an issue with the feature request, sorry it has taken a while. It's an interesting idea this feature and it might be easy to implement. I'll take a closer look as soon as I can

fnicastri commented 2 years ago

Hey, thanks for opening an issue with the feature request, sorry it has taken a while. It's an interesting idea this feature and it might be easy to implement. I'll take a closer look as soon as I can

I already have an implementation, you can see it in my fork at https://github.com/fnicastri/http_interceptor/tree/main

CodingAleCR commented 2 years ago

Oh, that's great, I'll take a look and see your implementation, hopefully it matches what I was thinking on doing and accept a PR on it.

fnicastri commented 2 years ago

any news?

fnicastri commented 1 year ago

🤷‍♂️

CodingAleCR commented 1 year ago

Hey, sorry for the delayed answer. I looked at your implementation and had my doubts about it, mostly because it could block all requests from being intercepted.

Instead, I would prefer to go on with the alternative of adding two methods to InterceptorContract called: Future<bool> shouldInterceptRequest() and Future<bool> shouldInterceptResponse(), both methods have a default implementation in case you are using extend and will be required if you are using implement on your different interceptors. This also means that you can optionally apply one interceptor and ignore the others or vice-versa.

Now regarding the RetryPolicy, there's a built-in bool shouldAttemptRetryOnException(Exception reason, BaseRequest request) and Future<bool> shouldAttemptRetryOnResponse(BaseResponse response) that you can override to avoid retrying a given request. Maybe you could elaborate a bit more just so I can understand why it might not be enough for your needs at the moment?

The implementation would look something like the following:

InterceptorContract

abstract class InterceptorContract {
  Future<bool> shouldInterceptRequest() async => true;

  Future<BaseRequest> interceptRequest({required BaseRequest request});

  Future<bool> shouldInterceptResponse() async => true;

  Future<BaseResponse> interceptResponse({required BaseResponse response});
}

Logger Interceptor Example:

class LoggerInterceptor extends InterceptorContract {
  @override
  Future<BaseRequest> interceptRequest({
    required BaseRequest request,
  }) async {
    log('----- Request -----');
    log(request.toString());
    log(request.headers.toString());
    return request;
  }

  @override
  Future<BaseResponse> interceptResponse({
    required BaseResponse response,
  }) async {
    log('----- Response -----');
    log('Code: ${response.statusCode}');
    log(response.toString());
    return response;
  }
}

Custom shouldInterceptRequest Interceptor Example:

class CustomRequestCheckInterceptor extends InterceptorContract {

  @override
  Future<bool> shouldInterceptRequest() async {
    if (someCondition) {
      return false;
    }

    return true;
  }

  @override
  Future<BaseRequest> interceptRequest({
    required BaseRequest request,
  }) async {
    log('----- Request -----');
    log(request.toString());
    log(request.headers.toString());
    return request;
  }

  @override
  Future<BaseResponse> interceptResponse({
    required BaseResponse response,
  }) async {
    log('----- Response -----');
    log('Code: ${response.statusCode}');
    log(response.toString());
    return response;
  }
}
CodingAleCR commented 1 year ago

This should be available in version 2.0.0-beta.6 which is just released 🎉

fnicastri commented 1 year ago

I'm very busy with other projects lately, sorry for the late reply.

I'll check the new methods in the next few days/weeks, I'm starting now a new Flutter project.

Thanks