Testing RESTful Services from the command-line with HttpRepl
Tags: dotnet, node, webdev, productivity
Published: 2019-08-08 15:32:01

Tools are the way we get things done and anytime a new one surfaces I am quick to jump in to see if it will help get my job done faster, better, write less code, test more effectively or even just promote ideas for better workflows.

This week, the .NET team published a new version on of the [HttpRepl](https://github.com/aspnet/HttpRepl), an open-source command-line tool for interacting with RESTful services.

* [Announcement Post: HttpRepl: A command-line tool for interacting with RESTful HTTP services](https://devblogs.microsoft.com/aspnet/httprepl-a-command-line-tool-for-interacting-with-restful-http-services/?WT.mc_id=devto-blog-shboyer)
* [GitHub/aspnet/HttpRepl](https://github.com/aspnet/HttpRepl)
* [Docs: Test web APIs with the HTTP REPL](https://docs.microsoft.com/aspnet/core/web-api/http-repl?view=aspnetcore-2.2&tabs=macos&WT.mc_id=devto-blog-shboyer)

Now, there is already a number of tools for testing APIs. [Postman](https://www.getpostman.com/) is well known, **curl** works for simple calls and then there is [HTTPie](https://httpie.org/) too for the command line.

`dotnet httprepl` is a bit different offering you the ability to work with your service(s) in the same manner you work with file and folders.

```console
dotnet httprepl http://localhost:3000
(Disconnected)~ set base "http://localhost:3000"

http://localhost:3000/~ set swagger http://localhost:3000/api-docs.json

http://localhost:3000/~ ls
.       [get]
hello   [get]
echo    [post]
todo    [get|put]

http://localhost:3000/~ cd todo
/todo    [get|put]

http://localhost:3000/todo~ ls
.      [get|put]
..     [get]
{id}   [get]

http://localhost:3000/todo~
```

In order to retrieve the list of ToDo items, the `get` operation is called on the `/todo` route just as you would do in a browser.

> Note that this example is written in Node.js using express. Although this is a .NET Core tool, it can be used for any HTTP RESTful service.

```console
http://localhost:3000/~ get /todo
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 150
Content-Type: application/json; charset=utf-8
Date: Thu, 08 Aug 2019 14:27:34 GMT
ETag: W/"96-xKQHQ6FTlo6NIFgo7DqTLvOqhgU"
X-Powered-By: Express

[
  {
    "id": 1,
    "name": "School supplies",
    "complete": false
  },
  {
    "id": 2,
    "name": "Haircut",
    "complete": true
  },
  {
    "id": 3,
    "name": "Pick up dog from vet",
    "complete": false
  }
]


http://localhost:3000/~
```

## Installing and configuration

The HttpRepl is a [dotnet global tool](https://docs.microsoft.com/dotnet/core/tools/global-tools?WT.mc_id=devto-blog-shboyer#install-a-global-tool), requiring the [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core/3.0?WT.mc_id=devto-blog-shboyer) to be installed. 

```console
dotnet tool install -g Microsoft.dotnet-httprepl --version "3.0.0-*"
```

## Enabling your HTTP Services

Out of the box, there is nothing you need to do to support the HttpRepl global tool. However, in order to support the `ls` operation to show the endpoints your API or service must have an [OpenAPI (aka Swagger)](https://swagger.io) specification to point to. By default, the HttpRepl will look for `/swagger/v1/swagger.json` 

> In ASP.NET Core [NSwag](https://docs.microsoft.com/aspnet/core/tutorials/getting-started-with-nswag?view=aspnetcore-2.2&tabs=visual-studio&WT.mc_id=devto-blog-shboyer) and [Swashbuckle](https://docs.microsoft.com/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-2.2&tabs=visual-studio&WT.mc_id=devto-blog-shboyer) are two options for creating an OpenAPI specification. [See the docs for how to achieve this in a few steps](https://docs.microsoft.com/aspnet/core/tutorials/web-api-help-pages-using-swagger?view=aspnetcore-2.2&WT.mc_id=devto-blog-shboyer).

For the Node.js ToDo example, I used [swagger-jsdoc](https://www.npmjs.com/package/swagger-jsdoc) and created a route for the Swagger UI at `/swagger` 

```javascript
app.get("/api-docs.json", (req, res) => {
  res.setHeader("Content-Type", "application/json");
  res.send(swaggerSpec);
});

app.use("/swagger", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
```

So I can easily test my API using the UI as well.

![](https://thepracticaldev.s3.amazonaws.com/i/gjs15twax41hvh0u4ztp.png)

# Setting up in VSCode

We could easily start the API from VSCode, fire up another terminal and type the starting command to initialize the HttpRepl, but where's the efficiency in that?

Visual Studio Code has the concept of [compounds allowing you to set up multiple configurations](https://code.visualstudio.com/docs/editor/debugging?WT.mc_id=devto-blog-shboyer#_compound-launch-configurations) in the launch.json file, starting up multiple debug configs.  This is especially helpful in situations where you might have a front-end and back-end system needing to debug as once.

In the following configuration, the **nodejsapi** is set to start as well as the **httprepl**.

```javascript
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "compounds": [
    {
      "name": "Launch w/HttpRepl",
      "configurations": [
        "nodejsapi",
        "httprepl"
      ]
    }
  ],
  "configurations": [
    {
      "name": "httprepl",
      "type": "coreclr",
      "request": "launch",
      "program": "dotnet",
      "args": ["httprepl", "http://localhost:3000"],
      "cwd": "${workspaceFolder}",
      "stopAtEntry": false,
      "console": "integratedTerminal"
    },
    {
      "type": "node",
      "request": "launch",
      "name": "nodejsapi",
      "program": "${workspaceFolder}/nodeapi/app.js"
    }
  ]
}
```

Hitting F5, or Debug to start the configurations and starts the API as well as the HttpRepl in the integrated terminal and I can test the `get /todo` and `get` methods without leaving VS Code and hit the breakpoints. 

![](https://thepracticaldev.s3.amazonaws.com/i/54ob70x88fmg10wowg54.png)

# Feedback

It's [open-source](https://github.com/aspnet/HttpRepl), please provide feedback on [GitHub](https://github.com/aspnet/HttpRepl)! 

Read the docs, [Test web APIs with the HTTP REPL](https://docs.microsoft.com/aspnet/core/web-api/http-repl?view=aspnetcore-2.2&tabs=macos&WT.mc_id=devto-blog-shboyer). There is much more that you can do with customization, running script files and more.

Participate in make your tools better. Thanks!