Giter Club home page Giter Club logo

Comments (14)

ryber avatar ryber commented on July 17, 2024

The HTTP spec says that there can be multiple of the same header, so appending is what I would expect. The previous behavior was a bug. It is possible to directly manipulate the Header (it's just a TreeMap<String, List<String>>) through getHeader but that is kind of awkward and breaks the build pattern. I understand the use case so I'm adding a headerReplace method

        Unirest.config().setDefaultHeader("foo", "bar");

        Unirest.get(MockServer.GET)
                .headerReplace("foo", "qux")
                .headerReplace("fruit", "mango")
                .asObject(RequestCapture.class)
                .getBody()
                .assertHeaderSize("foo", 1)
                .assertHeaderSize("fruit", 1)
                .assertHeader("foo", "qux")
                .assertHeader("fruit", "mango");

Should be on 3.2.01 in mvn central in about 20-30 minutes.

from unirest-java.

Catscratch avatar Catscratch commented on July 17, 2024

Hi. I got the same problem.

The HTTP spec says that there can be multiple of the same header, so appending is what I would expect.

That's right. But only in HTTP. In JAVA a setter should always overwrite. What you want is an Adder (addHeader...).

So from Java developer perspective I would assume:

  • setDefaultHeader: overwrites the old one with the new value
  • addDefaultHeader: will set (if nothing already in the map) or append (if map already contains entries)

I wouldn't touch the builder pattern with "headerReplace" because it makes no sense at all. Why would you ever replace the header in one building line?

from unirest-java.

ryber avatar ryber commented on July 17, 2024

the original method is just header, in fact the entire original unirest builder pattern avoids java words like set or get most of the time. This is because Unirest was originally part of a family of unirests, there were ones for PHP and Python and such.

I also want the method to align with IDE auto-complete and having it right next to .header( is nice for that purpose. I picked replace because this is what it's called in the TreeMap

Honestly I kind of hate the name and it's still early so we can change it, but I don't think converting just one of the methods to start to be Java-y works.

Would headerSet be any better? It didn't seem to imply exactly what was going to happen as well as replace.

from unirest-java.

Catscratch avatar Catscratch commented on July 17, 2024

I only reference to Unirest.config().setDefaultHeader.

So my suggestion would be:

  • Unirest.config().setDefaultHeader(...) -> overwrite
  • Unirest.config().addDefaultHeader(...) -> append

Unirest.header(...).header(...) should stay as it is. :-)

from unirest-java.

ryber avatar ryber commented on July 17, 2024

I think what is being asked for though is for the local builder to override the configured default header.

so

//Normally use JSON
Unirest.config().setDefaultHeader("Accept" "application/json");

// Except for this weird one
Unirest.get("http://somexmlservice").header("Accept", "application/xml")

right @philippendrulat ??

from unirest-java.

Catscratch avatar Catscratch commented on July 17, 2024

Philipp is a colleague of mine. And he wants excactly what I asked for. ;-)

Change a specific default header.

from unirest-java.

ryber avatar ryber commented on July 17, 2024

ah, so... can you help me understand why you would change the default configuration so much? It's really designed to be done once.

I don't have a problem adding the method you suggest BTW, just trying to understand

from unirest-java.

Catscratch avatar Catscratch commented on July 17, 2024

Of course.

We have some kind of request/response headers to track communication between our services. Therefore every request/response is passed through a javax.ws.rs.container.ContainerRequestFilter. There we modify header etc.

What we need on Unirest-Calls like Unirest.get(...) is a unique identifier in a specific header field. Now we can go through the entire code and add an addHeader(...) on each request or (better) can modify these requests in the Filter to only write the code once.

Maybe you got another good solution using Unirest?

from unirest-java.

ryber avatar ryber commented on July 17, 2024

So the only real issue is that Unirest's default configuration is static, so in a heavily used system you could end up replacing the header in the middle of a request. Unless you bind the configuration to the request in some way perhaps in a threadlocal.

Doing that has risks as well, Unirest creates a bunch of monitor threads, and Apache Http Client itself creates worker threads and it needs to be shut down properly.

You could spawn a entire client for each request as long as you shut it down at the end, or have the filter keep a static instance of the Apache client around and reuse it for each request.

from unirest-java.

Catscratch avatar Catscratch commented on July 17, 2024

Hm. Maybe you're right. Heavy load indeed is a problem. Especially on concurrent Unirest calls from different threads. I'll talk to Philipp tomorrow. Thanks for the hint!

from unirest-java.

ryber avatar ryber commented on July 17, 2024

I went ahead and added the add vs set methods on the config.

Kong unirest used a single monolithic client. As of 3.0 we now support multiple configurations so It would be possible to spawn a new config per request, but if you do that I think you should try to keep the Apache client around.

from unirest-java.

ryber avatar ryber commented on July 17, 2024

I wonder if there is a good use case for using Suppliers here. rather than literal values for some things. Particularly headers?

What if you could do

Unirest.config().addDefaultHeader("trace", () -> threadLocal.get())

from unirest-java.

philippendrulat avatar philippendrulat commented on July 17, 2024

I believe this use case is so unique that it would clutter the Unirest API.
We indeed forgot the threading problems of our solution.

I think you could use InheritableThreadLocal to push variables into the thread and its sub threads.

We are currently supplying our own HttpClient to unirest since we want to implement Tokenhandling and renewal of expired tokens. By attaching a default headers variable to the InheritableThreadLocal we are able to keep track of the default headers ourself.

After further discussion we really like the solution and we could make it work.
We would create a static InheritableThreadLocal (threadLocal) in the RequestFilter and add Unirest.config().setDefaultHeader("trace", () -> threadLocal.get()) in the static part of the filter class. This would solve our threading issues

from unirest-java.

ryber avatar ryber commented on July 17, 2024

I figured. I want to use it myself https://github.com/OpenUnirest/unirest-java/blob/master/CHANGELOG.md#3203

from unirest-java.

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.