Giter VIP home page Giter VIP logo

Comments (25)

wilka avatar wilka commented on May 3, 2024 9

I think I'd prefer just wrapping my response object in a Refit type, and have Refit do the usual magic for my object as well as include the header info in the Refit type. So something like

class RefitResponse<T>
{
    public HttpResponseHeaders Headers { get; set; }
    public HttpStatusCode StatusCode { get; set; }
    // ... whatever else ...  
    public T Content { get; set;}
}

Then you could have something like this in your Refit interface:

[Post("/some/asyncapi/{someId}")]
Task<RefitResponse<SomeResponse>> SomeAsyncRemoteApiCall(int someId);

and then you can access the header info via Task.Result.Headers

from refit.

auriou avatar auriou commented on May 3, 2024 1

Yes I used it to do on a single method.

But after I needed to recover the headers Rest at each call.

This is not very convenient and a lot of code has to be written.

To avoid this I have set up a specific HttpClientHandler to be notified of the change of headers.

here is my code.

One Test

[TestMethod]
public void HeaderSimpleTest()
{
var headers = new Dictionary<string, string>();
var ServerUrl = "http://localhost:26687/Service1.svc";
var handler = new HttpClientHeaderHandler
{
UpdateHeaders = dictionary => { headers = dictionary; }
};

        var client = new HttpClient(handler) { BaseAddress = new Uri(ServerUrl) };
        var restService = RestService.For<IService>(client);
        var resultBonjour = restService.Bonjour().Result;
    }

My Handler

public class HttpClientHeaderHandler : HttpClientHandler
{
public Action<Dictionary<string, string>> UpdateHeaders { get; set; }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var task = base.SendAsync(request, cancellationToken);
        var result = task.Result;
        if (UpdateHeaders != null)
        {
            var headers = result.Headers.ToDictionary(p => p.Key, p => string.Join(";", p.Value));
            UpdateHeaders(headers);
        }
        return task;
    }
}

My interface

public interface IService
{
    [Post("/Bonjour")]
    Task<string> Bonjour();

    [Post("/Connexion")]
    Task<authentRequest> Connexion([Body] authentRequest request);
}

from refit.

nbsoftware avatar nbsoftware commented on May 3, 2024 1

Any news on this issue?
My use case is simpler than that: I want to be able to distinguish a 200 OK from a 201 Created of a PUT request... and still let Refit do its magic stuff on my objects.
I've searched throughout all issues and didn't find any relevant info apart from this thread.
Any other solution than using Task<HttpResponseMessage>which will bypass all Refit magic?
Thanks

from refit.

clairernovotny avatar clairernovotny commented on May 3, 2024 1

Fixed in #414

from refit.

oatsoda avatar oatsoda commented on May 3, 2024 1

An update to the documentation on how to use the ApiResponse<T> would be really useful as it took me a lot of searching to find this :)

I assume Refit doesn't throw exceptions on non-success HTTP Status Codes?

from refit.

anaisbetts avatar anaisbetts commented on May 3, 2024

"This would be for making calls against APIs (ex the azure management api) that return a unique request-id as a response header, which can be used in support cases when something unexpected/bad happens"

So, that's one use-case

"in the case of asynchronous calls in which a call is made against the api such as swapping an azure deployment, in order to take that returned request-id and query its status in a future api call."

And that's a different one.

For the first one, I'd actually rather teach Refit how to translate types it doesn't recognize. What if your SomeResponse had a "Request-Id" property, and you provided a Func<HttpResponseMessage, SomeResponse>?

For the 2nd one, I'd probably rather have a way to explicitly implement some of the API methods and let Refit implement the others. Something like, if you supply an abstract base class, Refit will subclass it and implement all of the ones you don't do

from refit.

ray2k avatar ray2k commented on May 3, 2024

Well the main idea is getting the header from the response, whether or not the call returns a body or not. Having a simple one-property response model to capture the header or adding it to an existing response model would both be fine personally if refit was intelligent enough to map that response header to that property.

I would hate to start having to pass funcs around. The whole idea of refit is this automagic-proxying it-just-works experience right? Seems a bit off if you now suddenly have to fill in the gaps because it requires you to tell it what to do with response headers and pass in a func. Like how you model the calls now - you tell it what to do, but not how to do it, if that makes any sense.

from refit.

clairernovotny avatar clairernovotny commented on May 3, 2024

So this is almost a year old now. Is this still an issue with the latest changes? Is there a verdict on how this can be returned?

IMHO, an out parameter seems like it would fit in the best here.

from refit.

bennor avatar bennor commented on May 3, 2024

I actually tried to build it but I discovered that out parameters and async don't like each other. One thing I didn't try was using a Task for the value of the out parameter though - maybe that will work?

from refit.

clairernovotny avatar clairernovotny commented on May 3, 2024

Hmm...right, I forgot about that.
void Foobar ([header] out Task<Foo> blah);
Is really nasty because it's easy to not await it and there's no compiler warnings.

from refit.

bennor avatar bennor commented on May 3, 2024

Yeah, the other option is to provide a wrapper type e.g. ApiResponse<T> with similar properties to ApiException, and maybe even an implicit cast to the result type T. 😈

from refit.

clairernovotny avatar clairernovotny commented on May 3, 2024

Here's an idea...what if we have a special headers collection that can be optionally passed in and then filled out?
So

class ReturnedHeadersCollection : Dictionary<string,string> {} ...

var headers = ReturnedHeadersCollection.CreateRequest("header1", "header2", ...); // returns a dictionary with the keys and null values.

Task<SomeReturn> DoSomething(string foo, ReturnedHeadersCollection headers);

// extract the value
Debug.WriteLine(headers["header1"]);

from refit.

clairernovotny avatar clairernovotny commented on May 3, 2024

Having ApiResponse<T> could work too and be more generic. It could expose the entire httpresponse message too.

from refit.

bennor avatar bennor commented on May 3, 2024

Yeah, I'm open to either approach. I think having a wrapper for the response would be more flexible. It would solve a few more problems than just headers -- status code is another obvious bit of useful info we sort of throw away at the moment.

from refit.

clairernovotny avatar clairernovotny commented on May 3, 2024

Agreed. In fact, if we return status code as part of ApiResponse<T>, then I think it should have similar semantics to HttpResponseMessaege

  • don't throw if IsSuccessStatusCode is false
  • do check and throw if user tries to access the strongly typed .Content (or implicit cast if we add that)

from refit.

bennor avatar bennor commented on May 3, 2024

Sounds good to me. You all good with it, @paulcbetts?

from refit.

fonix232 avatar fonix232 commented on May 3, 2024

Any update on this? I'm in need of retrieving headers for a project, where a CSRF Token is returned via the header in the response.

from refit.

martingem avatar martingem commented on May 3, 2024

I would be too interested to have the status code.

from refit.

clairernovotny avatar clairernovotny commented on May 3, 2024

The latest code in master supports returning an HttpResponseMessage object and that would contain the headers.
https://github.com/paulcbetts/refit/blob/master/Refit/RequestBuilderImplementation.cs#L318

from refit.

bennor avatar bennor commented on May 3, 2024

Fairly sure that's been there since v1.x. Working with HttpResponseMessage is a decent workaround at the moment, but I think it would be nice to allow returning something with a bit more of a stripped down interface. I'll look at this when I next have some time.

from refit.

fonix232 avatar fonix232 commented on May 3, 2024

Good to know. It could be added to the documentation (no matter how small it is right now), so that others who want to work with received headers.

from refit.

auriou avatar auriou commented on May 3, 2024

Does that has been implemented since?

I would like get the header responses , how can we do?

from refit.

ahmedalejo avatar ahmedalejo commented on May 3, 2024

@auriou one way is to set the return type of your call to Task<HttpResponseMessage> then you could dig out the headers you want.

from refit.

KarinBerg avatar KarinBerg commented on May 3, 2024

I'm also very interested in an easier way to access response headers.

from refit.

streamtree avatar streamtree commented on May 3, 2024

What's the current status of this? I have paging information being return in the response header that I need access to.

from refit.

Related Issues (20)

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.