
Show HN: Unirest  - sinzone
http://unirest.io/
======
aroman
As cool (and pretty) as this is, I'm not sure I see the point to using this
over each language's best native http client. As someone else said, Python's
requests is fantastic, as is the mikeal/request library in node.

Point being, why would I choose this over a library which is hand-tailored to
fit the idioms of the specific language its written for? What advantage does
one get by forcing a relatively standard REST API across different languages?

~~~
nijiko
Hey, as the creator of the Node.js unirest library I'd like to say that I love
the request library in node. It is indeed fantastic, and constantly updated.
That's why I chose it as the underlying framework for the Unirest Node.js
library and thought an easier interface for using it would help out. Features
like supporting gzip requests, parsing cookies, etc... and the coding style of
Java / SuperAgent was the inspiration for it's syntax.

To answer your question aside from the additional features, I think each one
is specifically written for the language, built on-top of existing frameworks
to bring a easier interface... and what I have personally found developing
technologies using this (the site actually uses Unirest Node.js to generate
the source, and on our website we use this to show snippets in multiple
languages without a drastically different syntax) is the ease of going from
one language to the next without having to think too much, and a good pool of
documentation in-case you get stuck.

------
tfinch
Looks nice - but unfortunately as someone whose day-to-day language is python,
I'll give up my requests library [1] when you pry it from my cold, dead hands.

[1][http://www.python-requests.org/en/latest/](http://www.python-
requests.org/en/latest/)

Not mine mine, it should be obvious. I'm not Kenneth Reitz.

In all seriousness, would be interested to hear about differences/benefits...

~~~
fosk
I'm the creator of unirest-python. I love requests and I think it's a great
library, the Unirest libraries have been created to bring the same, easy,
usage experience across different programming languages. They're a good fit
for the 80% of simple consumption scenarios. We will improve all the Unirest
libraries to make them a good fit for the remaining 20% :)

I don't like the idea of libraries competing with each other, I personally
think they all get the niche of users who can decide which one to use
accordingly to the problem they try to fix.

~~~
yeukhon
Quick thing: you are expecting a header to be specified? If so, that's not a
good API design. You should fall back to keyword argument ``headers=``.

~~~
fosk
This is a good point, I've just opened an issue.

------
onion2k
Looking at the examples for Node and PHP, those are essentially two different
request libs with the same name. That lack of consistency is a problem - at
the very least anyone thinking "porting this app to <language> will be easy
because Unirest is available" will be in for a nasty surprise. At worst, it
shows a lack of planning and a lack of communication within the Unirest team,
and that's a _very_ big problem for anyone relying on the code.

Moving forward, I'd recommend working very hard on unifying your featureset
and API so it's consistent across all the versions.

~~~
nijiko
Hello, actually you now can, I've made it similiar to the Java syntax, but if
you want a more "PHP" style:

    
    
      unirest.get('http://httpbin.org/gzip', { 'Accept': 'gzip' }, 'Hello World', function (response) { });
    

or

    
    
      var Request = unirest.get('http://httpbin.org/gzip', { 'Accept': 'gzip' }, 'Hello World');
      Request.end(function (response) {});

------
joshguthrie
Thanks for this. I'm already using Unirest.php to build a client library for
my API and Unirest.rb is my obvious choice when I come to build the Ruby
client lib.

As aroman said, some languages have nice built-in capabilities but some...just
don't (PHP, I'm looking at you!). I love having this unified API which is very
intuitive (especially when coming back to PHP after...7 years).

Keep up the good work!

------
zamalek
You really need to make an effort to conform with established naming/casing
conventions in each language [1]. For example, your example page should read
[2] for .Net.

[1]: [https://github.com/Mashape/unirest-
net/blob/master/unirest-n...](https://github.com/Mashape/unirest-
net/blob/master/unirest-net/unirest-net/src/http/Unirest.cs) [2]:
[https://gist.github.com/jcdickinson/4dd0125d7c5af9d4878f](https://gist.github.com/jcdickinson/4dd0125d7c5af9d4878f)

------
zaidos
Small tip: It could just be me, but the color of some of the text makes it
difficult to read.

~~~
nijiko
Thanks, adding some contrast :)

~~~
kennywinker
On Safari 6.1 I can't scroll down to see the complete list of languages.
Screenshot: [http://i.imgur.com/s9O9l2u.png](http://i.imgur.com/s9O9l2u.png)

~~~
nijiko
I've moved the bar to the top :)

------
Killswitch
The PHP version seems to be meh... Gotta do a lot to get us away from Guzzle.
[http://guzzlephp.org/](http://guzzlephp.org/)

~~~
mikegirouard
I wouldn't have used the word "meh" to describe it, but I think that it's a
valid point to consider: why would I consider switching from Guzzle?

My attention is caught now that I see a composer.json. Friction is limited.
Now what?

~~~
Killswitch
It's meh because it's meh... The package is limited... I can do more by taking
a few minutes to write my own curl wrapper than add this to my composer.json
file, composer install and then not have what I need... I see in the
issues/pull requests someone fixed a basic necessity and it was closed as
"fixing this soon" instead of merging it... That right there isn't good.

------
seivan
I found code like ' int code = [response code];' Why 'int' and not
'NSInteger'?

That being said, I've been looking for a __NotWorking replacement, and this
might be it. Either this or I write my own once and for all.

Will give it a go! Also; [https://github.com/Mashape/unirest-
obj-c/pull/8](https://github.com/Mashape/unirest-obj-c/pull/8)

~~~
neilkimmett
Yep things like this, lack of class prefix, and using [NSDictionary
dictionaryWithObjectsAndKeys:@"application/json", @"accept", nil] instead of
modern literal syntax @{"accept": @"application/json"} are a bit of a red flag
for me.

~~~
seivan
Although I tend to agree, and I understand they might have their Java devs do
the OBJ-C library, but I still wanna' give them the benefit of the doubt, in
any case, it's easy to fix.

Most of the library seems pretty straight forward. I will have to dig deeper
when I get some time over. I'm debated wether or not to use this as work for a
project.

~~~
neilkimmett
Totally agree with giving them the benefit of the doubt, hence
[https://github.com/Mashape/unirest-
obj-c/pull/9](https://github.com/Mashape/unirest-obj-c/pull/9)

I still doubt as much thought has gone into it as a more mature library like
AFNetworking
([https://github.com/AFNetworking/AFNetworking](https://github.com/AFNetworking/AFNetworking))
though. Even then the new NSURLSession APIs in iOS7 pretty much remove the
need for a 3rd party networking lib.

------
mediumdeviation
This doesn't seem to be a good idea

    
    
        curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
    

[https://github.com/Mashape/unirest-
php/blob/master/lib/Unire...](https://github.com/Mashape/unirest-
php/blob/master/lib/Unirest/Unirest.php#L98)

~~~
yogo
Good catch. Yep generally not something you want to do in production and it
shouldn't be forced by a library. Aside from some edge scenario where the
server will be connecting to arbitrary endpoints taking the time to set
CURLOPT_{CAINFO,CAPATH} will allow VERIFYPEER to work properly.

While reviewing this section of the code they should also probably do manual
support for FOLLOWLOCATION or check open_basedir, which is usually set--or
should be.

------
jamesmoss
It's a shame the PHP lib has a completely static API. It makes it very hard to
mock when doing unit testing.

------
netghost
Minor nit, the ruby examples show:

    
    
        Unirest::post "http://httpbin.org/post", ...
    

That syntax is deprecated, you should probably just use:

    
    
        Unirest.post "http://httpbin.org/post", ...
    

I like the site though ;)

~~~
halostatue
[https://github.com/Mashape/unirest-
ruby/pull/3](https://github.com/Mashape/unirest-ruby/pull/3)

I'm not convinced that I'd use it, but this doesn't hurt to do. To be fair, my
changes haven't been tested.

------
btown
Interesting - does the Node version work if packaged for the browser i.e. by
Browserify? Of course, there would be caveats, but it would seem like that
would be very much in the spirit of this unified API.

~~~
nijiko
Since it is built ontop of request, you could swap out the node library for
this one: [https://github.com/iriscouch/browser-
request](https://github.com/iriscouch/browser-request) and it should work :)

(Thanks to you, I actually just found this, and will probably do this later
today!)

------
reznite
I believe this the old unicorn library which was submitted here a few times in
the past. [http://getunicorn.io/](http://getunicorn.io/) I believe

~~~
beaumartinez
Yes, I thought the same after I saw how it was available in a plethora of
languages. Glad they changed the name.

------
ImJasonH
The Java library's use of a static method makes it difficult to inject and
mock out for tests, requiring a wrapper class to be written by hand to make
such things possible.

------
clienthunter
I love Ruby so much that I shuddered a little when I saw the multi-line,
multi-hash method call in the example code that made it look like js.
Otherwise thumbs up.

------
tomphoolery
Heh, platform-independence...I guess that's one way to get them to use _your_
HTTP library, as opposed to the thousand other libs out there to do HTTP. ;)

But I like it! In all seriousness this is neat and I like the idea of
ubiquitous library syntax, especially for new programmers (which there are a
LOT of these days!). The API is reasonably simple and it's nice to have one
less thing to look up when experimenting with a new language.

------
felipesabino
It should really use cocoapods for the objc library, as it correctly uses
major package manager for all other platforms

~~~
kennywinker
It's on github ([https://github.com/mashape/unirest-
obj-c](https://github.com/mashape/unirest-obj-c)), so I expect someone will
submit a podspec in the next 24 hours. One of the awesome things about
CocoaPods is you can also write a podspec for a repo you don't control. So
even if the creators refuse to add CocoaPods support, you can still use
CocoaPods to import it to your project.

edit: went ahead and added a pull request for a .podspec. Only a little bit of
extra work, since I was writing one to test it out locally anyway.

~~~
fosk
I've merged the pull request, updated the spec, and submitted a pull request
to make Unirest available on CocoaPods:
[https://github.com/CocoaPods/Specs/pull/4867](https://github.com/CocoaPods/Specs/pull/4867)

Thanks for your contribution

------
MojoJolo
Nice one Augusto and Mashape. I checked Java and it is using Maven. I would
like to contribute with Scala and SBT.

~~~
sinzone
thx but the magic has been done by Chris, Nijiko and Marco. Yes, great, that
would be amazing. lmk when ready so we can add it.

------
ultimatedelman
The sticky footer on the bottom of the homepage blocks the bottom options. I'd
make it not sticky ;)

~~~
nijiko
It's been moved :)!

------
ozh
I recommend documenting that in PHP it's just a curl wrapper, as opposed to a
lib that can work with curl, streams, etc... (nothing condescending on '"just"
a wrapper'). Also give some insights on requirements (PHP 5.3+ I'd say?)

------
zampano
I actually used unirest.rb as one of the tools to teach my students about HTTP
requests. I loved the clear syntax and found the experience a lot more
straight-forward than many of the other HTTP libraries I came across. Thanks
for putting this together!

------
hayksaakian
If you could implement this for Unity3d using C# I'd be so happy

~~~
sinzone
It has been requested often so we'll definitely add it to the roadmap.

~~~
TheZenPsycho
It is dire. I am not a unity dev but I work with the other side of helping
them with server side stuff and unity provides pretty much no help with this.
It's roll your own http parsing and cookie handling library land.

~~~
skyebook
Shouldn't this mostly be handled by Mono? I was similarly surprised by the
amount of work it took to get some requests going in a Unity/C# project about
2 years ago.

~~~
TheZenPsycho
As I say, I am not a unity dev, but just guessing from what little I know
about it, I would say that mono is merely a language runtime that still
depends on the underlying platform for things such as networking. Unity, which
allows C# and Javascript, needs to have the same API for both languages, which
is ultimately implemented via npapi, activeX or pnaci, or you know, the other
platforms it runs on. So far as I know, mono doesn't have networking libraries
for all those different apis.

------
Groxx
This makes me realize what I've been missing in most Java request libraries.
And gives me ideas for building my own. Thanks for sharing!

~~~
fosk
As the creator of unirest-java, I will be happy if you want to contribute to
the project.

~~~
Groxx
If you have any ideas (I have little experience in building libs like this,
but will definitely learn): currently I need a streaming JSON decoder (which
handles base64-encoded blobs as some values, so values need to be stream-
decoded too, possibly with another custom step). So far this lib (and nearly
every other) seems to assume a pre-defined set of classes, and/or that you
want the full response before acting on it (no streaming access).

Before you ask, I don't control the response, so I can't do something more
sane :) And it's on Android, so memory can be quite restrictive, and GC hurts
a _lot_ with so much allocation.

I don't see an easy way to plug those requirements into this library.
Superficially it seems I can modify/add something inherited from BaseRequest
and add my own HttpClientHelper.requestAsync-style method to do this, but it's
yet another library that doesn't _quite_ allow this kind of thing natively.

But by the time I've understood and made those changes, I might as well just
do it all by hand in that particular request. This is especially true since my
code has to be read and understood by others I work with, and it makes
updating the Unirest library a much more error-prone event that might leave
people in the lurch since they didn't write the extension. There's no real
happy solution.

\--

Not that I really think it _should_ easily handle my case - it looks really
nice to use, and it's probably not worth it to you / most people, and my case
is weird and might ruin everything to properly support. But it's a minor thing
that annoys me a bit and makes me want to make my own (minor annoyances are a
major motivator for my personal projects). Before I can make anything decent
though I need to see a few more ways to do things, try a few crazy
architectures, etc. This has helped remind me what it can _look_ like at
least, and the code looks surprisingly clean underneath. Definitely a
worthwhile read :)

------
damusnet
Laravel kept complaining it couldn't convert Response Object to string or json
encode. Looked nice though :-(

------
Jemaclus
I love this, mainly because it's almost identical to my custom PHP remote
wrapper.

------
sirsar
Is there more documentation than what's listed when a language is clicked?

------
tomekmarchi
Very pretty, both in terms of code and site design.

------
the1
why not support proper http including caching

