Logo

dev-resources.site

for different kinds of informations.

Simplify API Testing with PhpStorm HTTP Requests

Published at
10/14/2023
Categories
php
phpstorm
webdev
api
Author
sean_kegel
Categories
4 categories in total
php
open
phpstorm
open
webdev
open
api
open
Author
10 person written this
sean_kegel
open
Simplify API Testing with PhpStorm HTTP Requests

A Convenient Alternative to Postman and Insomnia

API testing is a critical aspect of modern software development, ensuring that the services we build and integrate work seamlessly. While developers often rely on dedicated tools like Postman and Insomnia, what many aren't aware of is that JetBrains' IDEs, including PhpStorm, offer powerful built-in features for handling HTTP requests.

In this guide, I'll explore how PhpStorm's HTTP Client streamlines API testing and improves my development workflow right within the IDE. I'll delve into organizing requests, utilizing variables, and even importing and exporting requests. By the end, you'll have a solid grasp of how to leverage PhpStorm's capabilities for effective API testing.

Getting Started

To keep things organized, I prefer to create a folder in my project called ".http". This allows me to store all my HTTP requests in a single place. To ensure that these requests don't get accidentally committed, I will add the ".http" folder to my global .gitignore file. Read my article about using a global gitignore for more information. However, if I ever need to share these requests with my team, I can simply store them in a folder that is committed to the repository.

For this article, I will use the JSONPlaceholder - Free Fake REST API website, which provides various API endpoints that can be used for testing purposes.

Once I have the ".http" folder in my project, I can easily create a new request file called "Posts.http". This allows me to organize all my Post-related HTTP requests in one place.

Create an HTTP Request

Posts Requests

Get Posts List

In my "Posts.http" file, I create a request to list all posts. I can either type this request manually or use the UI to add it. With the UI, I will click on the plus + icon and select the request type.

Add GET Request

For listing posts, I will create a GET request. This will add the following content to the file:

GET http://localhost:80/api/item?id=99
Accept: application/json

###
Enter fullscreen mode Exit fullscreen mode

I will update it to use the JSONPlaceholder - Free Fake REST API. I will remove the Accept header for now.

GET https://jsonplaceholder.typicode.com/posts

###
Enter fullscreen mode Exit fullscreen mode

Once the request is ready, it's time to run it. I click the "Play" button, and the results appear in the console below.

Run a Request

Get Post

To get a specific post, I can add a new request to the file. I can even add comments to describe the requests, either using # or //.

# List Posts
GET https://jsonplaceholder.typicode.com/posts

###

# Get Post
GET https://jsonplaceholder.typicode.com/posts/1
Enter fullscreen mode Exit fullscreen mode

Also, I make sure to separate the requests with ### which is required by the .http syntax.

Create Post

To create a new post, I’ll add a POST request and a JSON body.

# List Posts
GET https://jsonplaceholder.typicode.com/posts

###

# Get Post
GET https://jsonplaceholder.typicode.com/posts/1

###

# Create Post
POST https://jsonplaceholder.typicode.com/posts
Content-Type: application/json

{
  "title": "Post title",
  "body": "Post body",
  "userId": 1
}
Enter fullscreen mode Exit fullscreen mode

It can also be helpful to add the Content-Type header to specify that JSON is being passed to the server.

Update Post

Updating a post is similar to creating a post, but I’ll use a PUT request.

# List Posts
GET https://jsonplaceholder.typicode.com/posts

###

# Get Post
GET https://jsonplaceholder.typicode.com/posts/1

###

# Create Post
POST https://jsonplaceholder.typicode.com/posts
Content-Type: application/json

{
  "title": "Post title",
  "body": "Post body",
  "userId": 1
}

###

# Update Post
PUT https://jsonplaceholder.typicode.com/posts/1
Content-Type: application/json

{
  "title": "New title"
}
Enter fullscreen mode Exit fullscreen mode

Delete Post

Finally, I can delete a post using a DELETE request.

# List Posts
GET https://jsonplaceholder.typicode.com/posts

###

# Get Post
GET https://jsonplaceholder.typicode.com/posts/1

###

# Create Post
POST https://jsonplaceholder.typicode.com/posts
Content-Type: application/json

{
  "title": "Post title",
  "body": "Post body",
  "userId": 1
}

###

# Update Post
PUT https://jsonplaceholder.typicode.com/posts/1
Content-Type: application/json

{
    "title": "New title"
}

###

# Delete Post
DELETE https://jsonplaceholder.typicode.com/posts/1
Enter fullscreen mode Exit fullscreen mode

Variables

Variables are a powerful tool when it comes to managing complex API testing scenarios. PhpStorm offers various types of variables, starting with Environment Variables.

Environment Variables

Environment variables can be used to store information such as usernames, passwords, authentication tokens, and more. They can also be used to support multiple environments. PhpStorm provides both public and private variables, which are merged before a request is made. To begin, create a public environment file.

Create a Public Environment File

This creates the file below:

Public Environment File

I will update the file to store a dev and production environment with a host and authentication token.

{
    "dev": {
        "host": "<https://jsonplaceholder.typicode.com>",
        "token": ""
    },
    "prod": {
        "host": "<https://jsonplaceholder.typicode.com>",
        "token": ""
    }
}
Enter fullscreen mode Exit fullscreen mode

I will leave the token empty for now and add it to the private environment file. I’ll create that now.

Create a Private Environment File

In this file, I will add the authentication tokens. It can also store usernames and passwords depending on the server authentication.

{
    "dev": {
        "token": "DEVELOPMENT_TOKEN"
    },
    "prod": {
        "token": "PRODUCTION_TOKEN"
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, I can add these variables to the requests.

# List Posts
GET {{host}}/posts
Authorization: Bearer {{token}}

###

# Get Post
GET {{host}}/posts/1
Authorization: Bearer {{token}}

###

# Create Post
POST {{host}}/posts
Authorization: Bearer {{token}}
Content-Type: application/json

{
  "title": "Post title",
  "body": "Post body",
  "userId": 1
}

###

# Update Post
PUT {{host}}/posts/1
Authorization: Bearer {{token}}
Content-Type: application/json

{
    "title": "New title"
}

###

# Delete Post
DELETE {{host}}/posts/1
Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

This approach saves me from having to repeat the full URL everywhere and works exceptionally well in scenarios where different environments require different hosts or tokens.

For APIs that have authorization, I can add an Authorization header with a value of Bearer {{token}}.

Before making a request, I will set the environment I want to use to replace my variables.

Select Environment

Per-Request Variables

Per-request variables allow me to set variables before specific requests, offering flexibility in customization. Here's how I set a per-request variable for the "Get Post" request:

# Get Post
< {%
    request.variables.set("postId", "10")
%}
GET {{host}}/posts/{{postId}}
Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

Now, when running the request, it will automatically replace postId in the URL with “10” from the postId variable. Note that request variables must be a string value.

Making a request with a pre-request variable

This method is particularly useful when I need to adjust variables for specific requests without affecting global environment variables.

Response Variables

Response variables can be really powerful. They allow me to set a new variable based on the response of a request. For example, after fetching the list of posts, I can create a new postId variable that grabs the first id from the lists of posts.

# List Posts
GET {{host}}/posts
Authorization: Bearer {{token}}

> {%
    client.global.set("postId", response.body[0].id);
%}
Enter fullscreen mode Exit fullscreen mode

Now, if I wanted to test updating the first post from the list, I can do the following:

# Update Post
PUT {{host}}/posts/{{postId}}
Authorization: Bearer {{token}}
Content-Type: application/json

{
    "title": "New title"
}
Enter fullscreen mode Exit fullscreen mode

The postId is set from previously calling the “List Posts” request, so it will be set to “1”. I can test by running the “Update Post” request.

Using a response variable

When running the request, I can see in the console that the postId was replaced with “1” in the URL.

Dynamic Variables

Dynamic variables are kind of like helper variables. They allow automatically generating common data on the fly, like UUIDs, random integers, timestamps, and more.

As an example, if I want to delete a random post, I can use the $random.integer(1, 100) dynamic variable. This will generate a random number between 1 and 100.

# Delete Post
DELETE {{host}}/posts/{{$random.integer(1, 100)}}
Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

When running the request, I see the following output, where the random number is 96.

Using a dynamic variable

For a complete list of available dynamic variables, refer to the documentation.

Importing and Exporting Requests

PhpStorm's built-in HTTP client simplifies importing and exporting requests, making it easy to transition my workflow. It handles importing cURL requests and even Postman collections.

cURL

With the following cURL code, I can import it right into a request file.

curl -X POST --location "<https://jsonplaceholder.typicode.com/posts>" \\ 
-H "Authorization: Bearer DEVELOPMENT_TOKEN" \\ 
-H "Content-Type: application/json" \\ 
-d "{ \\"title\\": \\"Post title\\", \\"body\\": \\"Post body\\", \\"userId\\": 1 }"
Enter fullscreen mode Exit fullscreen mode

To import, I click the import button and select the import type, cURL for this example.

Import cURL Command

This will bring up a new window to paste in the cURL code.

![Convert cURL to HTTP Request]
Image description

After clicking convert, the cURL request is now added to the file as an HTTP request.

cURL Request added to HTTP Request File

For exporting requests, I simply click the export button, select the environment to use for variable conversion, and the cURL code for the request is copied automatically.

Export to cURL

Postman

If I'm transitioning from Postman, JetBrains offers a plugin that allows me to import Postman collections into PhpStorm's HTTP requests. This plugin can ease the migration process.

Import from Postman

Conclusion

PhpStorm's built-in HTTP client and requests functionality offers an array of features that have significantly enhanced my API testing process. Beyond simplifying basic requests, I can execute JavaScript logic within < {% %} blocks, handle cookies, and even accommodate GraphQL requests. This all-in-one approach saves me the hassle of switching between different applications like Postman or Insomnia.

For more in-depth information and additional features, consult the PhpStorm documentation:

Thank you for joining me on this journey exploring PhpStorm’s HTTP client and requests!

phpstorm Article's
30 articles in total
Favicon
How to configure PHPStorm to work with Vite - Aliases
Favicon
Cursor AI Editor vs PhpStorm - a quick Laravel comparison
Favicon
Snapshots for AI: A “RAG-Like” solution for programming with LLMs
Favicon
Como instalar o PHPStorm no WSL2
Favicon
Enhance PhpStorm File Templates with Velocity 🧪
Favicon
Simple DX improvement in PHPStorm
Favicon
Interact with Docker containers without leaving PhpStorm
Favicon
Docker on WSL with PhpStorm - Best of both worlds
Favicon
Phpstorm Intellij search mode when focusing
Favicon
Simplify API Testing with PhpStorm HTTP Requests
Favicon
Running HTTP requests in PhpStorm
Favicon
PhpStorm with Docker
Favicon
How to select a File Using Ctrl+P In PHPstorm as I did in VSCode and VSCodium
Favicon
Automatic Git Commit and Push on Save using PHPStorm
Favicon
XDebug, PHPStorm, Docker, macOS Ventura
Favicon
Laravel Sail & XDebug
Favicon
Atalhos para ser mais produtivo no PHPStorm
Favicon
Comment Publier Rapidement un Projet sur GitHub
Favicon
Impressions on GitHub Copilot and PHPStorm - March 2023
Favicon
Using Laravel Sail alongside PhpStorm
Favicon
Pair programming in PHPStorm
Favicon
PHPStorm Tips #10 : Last Edit Location
Favicon
PHPStorm Tips #9 : Zoom ton code
Favicon
PHPStorm Tips #7 : Naviguer dans le YAML
Favicon
My barebones React component snippet
Favicon
PHPStorm Tips #5 : Toute la pouissance des Live Templates
Favicon
PHPStorm Tips #6 : Les contextes
Favicon
PHPStorm Tips #8 : Rechercher et ouvrir plusieurs fichiers
Favicon
PHPStorm Tips #2 : Select Occurences
Favicon
PHPStorm Tips #4 : Extend Selection

Featured ones: