Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Hurl – Run and test HTTP requests with plain text, curl and Rust (hurl.dev)
223 points by jicea on Oct 5, 2021 | hide | past | favorite | 49 comments



We're releasing a new version of Hurl, a simple HTTP cli tool built on top of libcurl and Rust.

Hurl allows running HTTP requests defined in a plain text format. It can be used to fetch data, or play a scenario (sequence of requests), asserting responses along the way. With its textual format, it is aimed for both devops and developers. With its command-line usage/simple unique binary, it is aimed for both local dev and continuous integration.

An Hurl sample:

  GET https//example.org/books
  
  HTTP/1.1 200
  [Asserts]
  jsonpath "$.validated" == true
  jsonpath "$.books" count == 12
  jsonpath "$.books[2].name" == "Dune"
Since our first "Show HN" submission [1], we have made the following changes:

- full native support on Windows

- improve Hurl file format syntax (with md5, sha1, sha256 asserts for instance)

- add a tutorial on how to use Hurl [2]

- add a simple interactive mode

- a lot of bug fixes!

In our roadmap, we want to have a better support for package manager (brew, apt etc...), better error feedbacks.

We're looking for contributions on improving/correcting our documentation, build an UI client above Hurl, better IDE tooling integration.

And last but not least, we would be happy to have feeback on it!

[1] https://news.ycombinator.com/item?id=25655737

[2] https://hurl.dev/docs/tutorial/your-first-hurl-file.html


This looks really cool! Very promising!

Is it possible to chain a value from a response to the next request? This would be useful for testing.

My understand is that between the header and the body there has to be a new line[0], in the docs seems like it's skipped[1], does it affect functionality if skipped? or is it intentional?

Thanks!

[0]: https://www.lifewire.com/hypertext-transfer-protocol-817944 [1]: https://hurl.dev/index.html#also-an-http-test-tool


Yes, this is possible to chain a value from a response to the next request. The value is extracted and stored in a variable. This variable can be reused afterward.

    # Get home:
    GET https://example.net
    
    HTTP/1.1 200
    [Captures]
    csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
    
    # Do login!
    POST https://example.net/login?user=toto&password=1234
    X-CSRF-TOKEN: {{csrf_token}}
    
    HTTP/1.1 302


Looks like something we could actually use for some API smoke tests. I'll bookmark it, thank you!


The first feature I look for in tools like this is the ability to run requests concurrently. Of course some requests depend on others, but there are often a lot of requests that can be run concurrently to save time. I don't see how to do that with hurl.


This is not possible yet.

We have related issues: - https://github.com/Orange-OpenSource/hurl/issues/87 - https://github.com/Orange-OpenSource/hurl/issues/88

Running several Hurl files concurrently (and independently) is clear and we will probably add in the next few months.

Running requests concurrently in the same Hurl file will be more complicated. The Hurl language has to describe a clear semantic about it.


Can you read a request from stdin? It could just be catted through GNU parallel to launch many hurls concurrently.


Yes you can.

    $ echo GET http://google.com | hurl
    <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
    <TITLE>301 Moved</TITLE></HEAD><BODY>
    <H1>301 Moved</H1>
    The document has moved
    <A HREF="http://www.google.com/">here</A>.
    </BODY></HTML>


The Hurl web app was great and has saved me a ton of time in the past.

Recently I've replaced Hurl and Postman with the REST Client extension for VS Code.

https://marketplace.visualstudio.com/items?itemName=humao.re...


It's still there: https://www.hurlit.com/about/

Recently acquired in fact.


Interesting; is that someone rehosting the original app?

https://hurl.it/ got bought at some point.


It was relaunched 5 months ago, and if you go on WayBack Machine, it seems it hasn't changed at all, except perhaps to add a Captcha.

I think they probably plan to do more with it, and thus there's a name conflict for hurl.dev.


A lot of people use tools like hurl for integration and smoke tests during CI runs. The extension looks nice, but it is limited in that way.


So what we really need is a nice VS Code extension for Hurl.


Reminds me of https://github.com/pashky/restclient.el. Nice to see an editor-agnostic version of this idea, great job!


I suggested that same, then I saw your comment, so I deleted my comment and upvoted yours instead. Happy to see these gems becoming more popular.


Me three!


Also similar to the Jetbrains HTTP textual client: https://www.jetbrains.com/help/idea/http-client-in-product-c...

It uses JS to perform assertions though.


There's also dot-http[0] which aims to provide a similar interface to what IntelliJ's requests feature has. I've used it a few times. It's a shame development has died, so hopefully Hurl can take its place.

[0] https://github.com/bayne/dot-http


When I saw this I was thinking of IntelliJ's HTTP client[1]. I hope that a standardised format can come out of this.

[1] https://www.jetbrains.com/help/idea/http-client-in-product-c...


Yes, we began to work on Hurl three years ago and the file format was "accidentaly" close to IntelliJ's HTTP file format. For the request part, it's not a coincidence since Hurl and IntelliJ's HTTP looks like "bare" HTTP format. They differ drastically on the response tests.

We keep working on Hurl because our main goal is to be able to easily run integration tests on a CI or locally in a terminal, which can be difficult with IntelliJ.

But yes, this shows that is really a need for such a tool.

For reference, IntelliJ format:

  GET https://httpbin.org/status/200
  
  > {%
  client.test("Request executed successfully", function() {
    client.assert(response.status === 200, "Response status is not 200");
  });
  %}

  ### Failed test: check response status is 200
  GET https://httpbin.org/status/404
  
  > {%
  client.test("Request executed successfully", function() {
    client.assert(response.status === 200, "Response status is not 200");
  });
  %}


> We keep working on Hurl because our main goal is to be able to easily run integration tests on a CI or locally in a terminal, which can be difficult with IntelliJ.

I completely agree with this. Its pushed me away from using IntelliJ's feature. I will always prefer a tool that can be built into a CI pipeline over one that has handy IDE integration.


The Jetbrains format can also be run from the CLI or CI: https://renatoathaydes.github.io/rawhttp/rawhttp-modules/req...


Me too. I attempted to migrate to using this tool in Pycharm, (I have often used Paw for this kind of thing) but it felt a bit unfinished last year.

Do you use it as part of a web dev workflow?


I work in the same team as the two authors and we use it on a pretty large project : an online shop, and a few other smaller ones. We run hurl tests on every branch of our projects, via Gitlab pipelines.

We test both HTML and JSON endpoints and those integration tests are a good safety belt.


At first I thought it was this: https://www.hurlit.com/about/


This is looking like what Postman should have been.


Postman used to be nice and simple like this, and there used to be hurl.it as a web interface for making HTTP requests. I used that a lot. I'm guessing it got abused, though.


Tangentially related: does anyone do Pact-like consumer-driven testing?

Are there good articles about testing services in Rust?


Ah reminds of hurl.it - loved that service...


https://curl.link/

Shameless plug, built this small tool to share curls.


thanks! this looks like something i could use.

p.s. coolest and most intuitive name btw.


Does no one remember hurl.it? It's a web-based http request tool that has already been using the name Hurl since 2009: https://www.hurlit.com/about/ ... originally co-created by one of GitHub's founders no less.


I'm actually curious about the name.

OP says "an Hurl request" above. So it's pronounced with a silent "H"? Like "An hour of time?"


i'd pronounce it the same way i read it, hurl something.


Keep up the good work :)


This is seriously cool, and I would use it frequently... if only there was a rust compiler in my computer.

Since it is a somewhat "thin" wrapper around curl, are there deep reasons for it to be written in Rust as opposed to, say, C or posix shell? Was learning Rust one of the main goals of this project? (not that there would be anything wrong with that, just asking).


https://hurl.dev/docs/installation.html

> Precompiled binary is available at hurl-1.3.1-x86_64-linux.tar.gz

https://github.com/Orange-OpenSource/hurl/releases/download/...

> For Debian / Ubuntu, Hurl can be installed using a binary .deb file provided in each Hurl release.

> hurl-bin package for Arch Linux and derived distros.

> An installer is available at hurl-1.3.1-win64-installer.exe

Just glancing at a few files, main.rs is already over 500 lines, which means shell would be impractical. C is a very difficult language to learn and to use correctly, so in the long-term there will be more Rust (and Go, and Python) programmers than C programmers. I think that is a good reason for projects to choose other languages.

In fact, one might equally ask why it wasn't written in Python - Python is safer than C, far easier, and performance doesn't sound critical for an HTTP debugger meant to be used interactively by a human.

We're probably already far past the point of "There are more competent Python programmers than competent C programmers."


As a matter of fact, our first implementation of Hurl was written in Python. We switch to Rust because:

- we're a 30 developper team with Linux, Windows and macOs computers. Installing Hurl with Python on Windows boxes was always a challenge and the single drop Rust binary has been a relief for us,

- in a CI, we really want to run tests as fast as possible. The Rust version (the actual one) seems a lot faster that our Python prototype (certainly due to our lack of optimisation in our Python code)


Good choice, Rust is much better than python for concurrency, and that might be of interest in a future release :)


>We're probably already far past the point of "There are more competent Python programmers than competent C programmers."

Maybe this is the point where we need to start thinking about where we went wrong? I know that nobody cares about performance anymore, but if anybody is really thinking about Python as a replacement for C then that makes me sad.


I don't think the claim is that Python is a good replacement for C. But there are probably more (business) problems for which Python is the right tool to solve it then problems for which C is the right tool.

C is also a lot harder than Python to learn.

So for these reasons there are more Python programmers than C programmers.

For some subset of problems for which C is a good tool, Rust is a good alternative, arguably with less foot guns. For some other problems that are solved with C, Golang is a good alternative.

So in the end C is losing marketshare because of all these reasons.


I think the success of Go and Rust show that lots of people care about performance. But it has to come second to correctness and safety/security, and C makes achieving those things very difficult compared to other languages.


Others have already commented that you don't need a rust compiler for this. But it's also worth noting that compiling Rust programs is typically much more straightforward than compiling C programs, even if you account for installing the Rust compiler as part of the process.

The process would be:

- Run the `curl | bash` command from https://rustup.rs/ to install rust via rustup

- If you have a non-standard shell configuration that rustup can't detect, then add `~/.cargo/bin` to your PATH.

- Clone the git repository containing the program you wish to compile

- Run `cargo build --release` in the source directory.

That's it, and that will work across all major platforms and almost all Rust programs.


    rustup: unrecognized OS type: OpenBSD
EDIT: googling around, it seems to be possible to build rust programs for openbsd, but it does not really work "out of the box". May try to install it this weekend.


Ah, OpenBSD looks like a bit of an exception in terms of platform support. FreeBSD and NetBSD both have Tier 2 (which is really the minimum level you want for a compiler host platform), but not OpenBSD.


You don't need a Rust compiler as prebuilt binaries are available for your system. https://hurl.dev/docs/installation.html

Relating to the choice of Rust, we think that it is the best language for this type of command-line tool. Performant like C/C++, but way safer to develop. And using native existing libs such as libcurl is possible.


Is a Rust compiler really needed? They say there are precompiled binaries available and the package is on several package managers.


In the installation page they just say to download the prebuilt binaries for your system, no need to compile it your self




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: