Many users have requested support for request variables in the HTTP files of Visual Studio. With request variables, you can send HTTP requests and then use data from the response or request in any subsequent requests sent from the HTTP file. We have also added support for the shared environment $shared, which allows you to share variables across different environments. In this article, we will outline the new support for request variables and more. All features listed in this article are included in Visual Studio 2022 17.12+.
Request Variables
When using APIs, it is common to obtain a value from an endpoint and then use that value in subsequent requests. This can be achieved by using request variables. We have documentation for request variables, but we will also discuss everything here. A more common scenario for using request variables is when you call an endpoint to authenticate with the API and obtain a token that can be used for future requests. The example request below is from David Fowler’s TodoApi example. This API has an endpoint where you can create a new user by providing a username and password. This is the endpoint we are making the request to.
@username = bloguser# login and save the response as "login"# @name loginPOST {{TodoApi_HostAddress}}/users/tokenContent-Type: application/json{ "username": "{{username}}", "password": "{{password}}"}###
In this case, the username is defined in the HTTP file, but the password is securely stored using HTTP Environments. The request below is sent to the /users/token endpoint, where we pass the username and password as part of the HTTP request body. Making it a request variable (sometimes also called a named request) is special due to the line above the comment.
# @name login
After sending this request in Visual Studio, you can retrieve values from the response or request. In the code snippet below, you can see how we use the request variable from login to access the token returned as part of the response when submitting the login. The response from login contains a token. Now that we are logged in, we can create a TODO item with the request below.
# Create a TODO item# @name todo1POST {{TodoApi_HostAddress}}/todosAuthorization: Bearer {{login.response.body.$.token}}Content-Type: application/json
{ "title": "Write blog post"}###
In this request, we extract the token value and use it to specify the value of the Authorization header. The syntax is {{login.response.body.$.token}}. Let’s take a closer look at the syntax.
{{login.response.body.$.token}}
The table below summarizes the syntax for using values from request variables:
Element |
Description |
requestVarName |
The referenced request variable. |
response|request |
Whether to extract the value from the response or request. |
body|headers |
Whether to extract the value from the headers or body of the request or response |
*|JSONPath|XPath|Header |
Computational expression for result extraction For requests returning a JSON body, use a JSONPath expression. For requests returning an XML body, use XPath. * will return the entire result. Cannot use * when extracting from headers. |
For the example request above, we extract the token from the response and pass it as a header for the request to the /todos endpoint. After sending this request, the returned result is as follows:
{ "id": 36, "title": "Write blog post", "isComplete": false}
Now that we have created a TODO item, we can update that item with the request below. If you notice, the above request declared a request variable named todo1, which we can use to reference values in the response or request. Let’s update the title by appending “today” to the current title. The request below will update the TODO item. We will use PUT since this is an update to an existing item.
PUT {{TodoApi_HostAddress}}/todos/{{todo1.response.body.$.id}}Authorization: Bearer {{login.response.body.$.token}}Content-Type: application/json
{ "id": {{todo1.response.body.$.id}}, "title": "{{todo1.response.body.$.title}} today", "isComplete": {{todo1.response.body.$.isComplete}}}###
In this request, we populate the body of the PUT request with data from the original todo1 request. Note that the title property appends “today” to the end of the existing title. After sending this request, the result is:
{ "id": 36, "title": "Write blog post today", "isComplete": false}
Here, you can see that the title of the blog post has been successfully updated. In these examples, I have shown how to handle “flat” JSON results, but you can use any JSONPath expression to extract data from the response or request body. If the endpoint returns XML, use XPath expressions instead of JSONPath. Let’s continue discussing support for $shared.
$shared
When using HTTP environments, you can define multiple different environments for HTTP requests. For example, you can create a development environment that references a locally running API and create a testing environment when you want to send requests to a remote testing environment. In these cases, you may want to declare a variable that is available across all environments. This is exactly what the new $shared environment is designed to do. HTTP environments are defined in a file named http-client.env.json or http-client.env.json.user. If you create an environment named $shared, then these variables will be available in any environment. If a variable is declared in both $shared and a standard environment, the value defined in the standard environment will take precedence. Below is an example HTTP environment file that includes a $shared environment and two standard environments.
{ "$shared": { "message": "Default msg from Shared", "username": "httpfile-user", "hosturl": "http://example.com/api/sample" }, "dev": { "hosturl": "http://localhost:5000/api/sample" }, "prod": { "message": "Message from prod environment" }}
This is a very basic HTTP environment file where, in addition to $shared, we also define dev and prod environments. In the dev environment, the value of hosturl has been customized to point to localhost, while the prod environment has a custom message value. To illustrate how this works, we will use the third-party open-source site httpbin.org. For API developers, httpbin.org is a great tool. We will create an HTTP file that makes a request to httpbin.org and lets it return the provided values. We will use the /headers endpoint so that httpbin echoes back the headers we send to it. Here is the request we will send:
GET https://httpbin.org/headersX-Message: {{message}}X-User: {{username}}X-Hosturl: {{hosturl}}
###
This request will use the variables defined in the HTTP environment in the request sent to httpbin.org. Just a reminder, you can select the environment in the dropdown menu at the top right of the HTTP file editor. I set the environment to dev, and the result from httpbin.org is as follows.
{ "headers": { "X-Hosturl": "http://localhost:5000/api/sample", "X-Message": "Default msg from Shared", "X-User": "httpfile-user" }}
In the response, I removed some unrelated headers. We can see that these values are being populated as expected. The value of hosturl is localhost as specified in the dev environment, while the other values come from $shared. When we switch the environment to prod and send the same request, the response is as follows:
{ "headers": { "X-Hosturl": "http://example.com/api/sample", "X-Message": "Message from prod environment", "X-User": "httpfile-user" }}
The values of hosturl and message have both changed. The values of hosturl and username come from $shared, while the message comes from the value provided in the prod environment. If you send a request without selecting an environment, the values in $shared will be available. Now that we have introduced the new support for $shared, we will conclude this blog post.
Summary
In this article, we introduced two new features of HTTP files: request variables and $shared in HTTP environments. With support for request variables, you can now create “chained” requests that retrieve values from previous requests. This will allow you to practice APIs in a more realistic way than before. Additionally, with $shared, you can now share variables across environments, making it easier to work with HTTP environments. If you are not familiar with HTTP files, please check the documentation for more information.
This update was inspired by feedback from users like you. You can share your feedback with us through the developer community: by reporting bugs or issues and sharing your suggestions for new features or improvements to existing features.
Original link: https://devblogs.microsoft.com/visualstudio/http-file-updates-for-request-variables-and-more/