Replacing Postman with Rider

Dave Megins Nicholas
ASOS Tech Blog
Published in
5 min readSep 27, 2023

As you might have read, Postman is deprecating the scratchpad feature. We’ve been using this feature to create and share collections of requests, which come in handy for manually interacting with APIs in our non-prod environments. We commit the collections and environments to git repositories for posterity. Now that’s going away we’ve been looking for alternatives. There are other apps that work a lot like Postman, we could write some custom code but that’s a lot of effort for a thing we’re doing rapidly.

Enter Rider. Over the last few years our team has adopted Rider as our primary IDE. It has an HTTP Client built in which has completely solved our problems with only a little work.

The Basics

An HTTP Client takes a file of request descriptions and runs them. Nice and simple. A GET request looks a like this (these URIs are entirely made up):

# Example Collection

###
# @name Health Check
GET https://example.com/healthcheck

It has a collection name, request name, then the verb, and URI. You can run that like a unit test with Rider and see your health check result.

You probably have multiple environments which change your URIs. You can specify these differences in an environment file http-client.env.json:

{
"dev":{
"baseUri ":"https://dev.example.com",
"client" :"dev-client"
},
"staging":{
"baseUri" : "https://staging.example.com",
"client" : "staging-client"
}
}

You can then use the variables defined in the environment file in your requests like so:

# Example Collection

###
@name Health Check
GET {baseUri}/healthcheck

Suppose you want to include some headers on your request, that’s easy with some key value pairs below the URI:

###
@name Health Check
GET {baseUri}/healthcheck
client-tye: {client}

Bodies of requests can be included too with some JSON:

###
@name Create User
POST {baseUri}/user/create
{
"name" : "Gildor Inglorion",
"hairColour" : "Golden"
}

If the bodies of your requests start getting large or you’re repeating them all over, you can store them in a JSON file and specify them more concisely. Imagine the JSON for Gildor above is in a file at ./bodies/createUser.json relative to your .http file:

###
@name Create User
POST {baseUri}/user/create
> ./bodies/createUser.json

API Tokens

I assume your APIs have some access controls. Maybe in non-prod you can call an API with some details and get a token for that test environment. If that’s the case, you can create a request that gets your token and saves it in your request environment. Extend your environment JSON to this:

{
"dev":{
"baseUri ":"https://dev.example.com",
"client" :"dev-client",
"bearerToken" : ""
},
"staging":{
"baseUri" : "https://staging.example.com",
"client" : "staging-client",
"bearerToken" : ""
}
}

Now you can create a new request that calls your Identity API and execute a script that will use the response:

###
@name Get Token
GET https://example.com/token
{
"env" : "dev"
}
> ./scripts/store-token.js

What’s ./scripts/store-token.js?

client.log("Token :" + response.body.Token)
client.global.set("bearerToken" "Bearer " + response.body.Token)

Scripts executed by Rider have access to two variables. response gives you access to the response from the request, I’m assuming your Identity API returns the token in the body. client provides the interface with Rider, which allows you to log to the output window and save environment variables. So this tiny script sets the value of the bearerToken environment variable to the value returned from your Identity API. This data persists between requests you make with the HTTP Client, so long as they’re against the same environment. If you swap environments with the dropdown then you’ll have to get a new token.

Now you can use the bearer token in future requests:

###
@name Get Gildor
GET https://example.com/users/gildor
Authorization: {{bearerToken}}

You can use the Rider’s Run/Debug Configurations to create chains of requests. With this you can press one button to get a token and find out about Gildor. Select your Get Gildor request in the Run/Debug Configurations window and add a Before Launch step, select “Run Another Configuration” and select the Get Token request. Check the “Store as project file” box to make this config persist between restarts. Now you can run Get Gildor and it’ll run Get Token first (which saves a Bearer token) then Get Gildor.

Run/Debug Configurations with a Before launch step to execute the Get Token requests to create a bearer token

Certificate Tokens

Maybe your API requires a service token. That token is created using a certificate you have installed on your machine. Create some code (your choice of language) to run on your machine, have that code save the service token to a .js file on disk which exports a const. So the output of the code would be writing to C:\Temp\bearerToken.js with the content:

export const serviceToken = "yourServiceTokenHere"

Now in Rider create a script that sets an environment variable to the value in bearerToken.js with a script like loadServiceToken.js:

import {serviceToken} = from "C:\\Temp\\token.js";
client.global.set("serviceToken", "Bearer " + serviceToken)

Edit the Run Config of whatever request needs a service token, add a Before Launch step that runs your code that generates a service token.

Finally have the HTTP Client run loadServiceToken.js:

###
< scripts/loadServiceToken.js
@name Get Gildor
GET https://example.com/users/gildor
Authorization: {{serviceToken}}

Now when you run Get Gildor: Rider will execute a Before Launch step that calls your native code, generating a service token that is saved to disk. Then Rider starts the HTTP Client work which executes loadServiceToken.js that reads the token from disk and sets it as an environment variable. Finally the HTTP Client makes a GET request using the Service Token in the request header.

Conclusion

There’s a learning curve here but HTTP Clients are very powerful. We’ve got everything we used in Postman and more.

  • It’s integrated into our development environment, like some sort of IDE!
  • The requests are executed directly from the repo, no importing into Postman to run them then exporting any changes
  • Environments are cleaner. My Postman installation was clogged with loads of very similarly named environment from the various services we support

The only disadvantage is that you need a Rider licence but if you ask anyone in our team that’s really another benefit in disguise.

Visual Studio and VS Code have HTTP clients too, but they aren’t currently as fully featured as Rider. Hopefully going forward programs can standardise the format and allow for interoperable requests and environments.

I hope this has helped. Let me know if you’ve got any cool tricks or simplifications.

--

--