Axios HTTP/2 Adapters — Complete Guide with Examples
In this tutorial, you'll learn about Axios HTTP/2 adapters. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Axios HTTP/2 adapters enable multiplexed streams, server push, and header compression for improved performance in Node.js environments, replacing the default HTTP/1.1 transport.
What You'll Learn
By the end of this tutorial, you'll configure HTTP/2 adapters, understand multiplexing benefits, use custom adapters for testing, implement mock adapters, and handle Adapter-specific features.
Why It Matters
HTTP/2 reduces latency through multiplexing (multiple requests on one connection), header compression, and server push. For Node.js services making many API calls, HTTP/2 can significantly reduce connection overhead and improve throughput.
Real-World Use
Doda Browser's backend services use HTTP/2 Axios adapters for inter-service communication. Multiple concurrent requests to the same server share one connection, reducing latency by 30% compared to HTTP/1.1 connection pooling.
Where This Fits in Your Learning Path
flowchart LR
A["Cookies & Auth"] --> B["**HTTP/2 Adapters**"]
B --> C["Axios Project"]
C --> D["Axios Advanced"]
style B fill:#f97316,stroke:#c2410c,color:#fff
style A fill:#e5e7eb,stroke:#9ca3af,color:#374151
style D fill:#22c55e,stroke:#16a34a,color:#fff
Installing HTTP/2 Adapter
HTTP/2 support requires an additional package in Node.js.
npm install @azure/core-http-compat axios-h2
Or use the built-in http2 module with a custom adapter:
import http2 from 'http2'
import axios from 'axios'
const client = http2.connect('https://api.example.com')
const response = await axios.get('https://api.example.com/data', {
adapter: async (config) => {
return new Promise((resolve, reject) => {
const req = client.request({
':path': config.url,
':method': config.method.toUpperCase(),
...config.headers
})
let data = ''
req.on('data', chunk => data += chunk)
req.on('end', () => {
resolve({
data: JSON.parse(data),
status: 200,
statusText: 'OK',
headers: {},
config,
request: req
})
})
req.on('error', reject)
req.end()
})
}
})
Expected output: The request uses HTTP/2 multiplexing over a single persistent connection.
Multiplexing Benefits
HTTP/2 multiplexes multiple requests over one connection.
import http2 from 'http2'
const client = http2.connect('https://api.example.com')
async function makeRequest(path) {
return new Promise((resolve, reject) => {
const req = client.request({ ':path': path, ':method': 'GET' })
let data = ''
req.on('data', chunk => data += chunk)
req.on('end', () => resolve(JSON.parse(data)))
req.on('error', reject)
req.end()
})
}
// All three requests share one HTTP/2 connection
const [users, products, orders] = await Promise.all([
makeRequest('/api/users'),
makeRequest('/api/products'),
makeRequest('/api/orders')
])
Expected output: Unlike HTTP/1.1 which opens separate connections, HTTP/2 sends all three requests over one multiplexed connection.
Custom Mock Adapter for Testing
Create a mock adapter for testing without a server.
function mockAdapter(config) {
const mocks = {
'/api/users': { data: [{ id: 1, name: 'Alice' }], status: 200 },
'/api/error': { data: { error: 'Not found' }, status: 404 }
}
const mock = mocks[config.url]
if (mock) {
return Promise.resolve({
data: mock.data,
status: mock.status,
statusText: mock.status === 200 ? 'OK' : 'Not Found',
headers: { 'content-type': 'application/json' },
config
})
}
return Promise.reject({ message: 'No mock for ' + config.url })
}
const response = await axios.get('/api/users', { adapter: mockAdapter })
console.log(response.data) // [{ id: 1, name: 'Alice' }]
Expected output: The mock adapter returns pre-defined responses without making network calls, useful for unit tests.
Adapter Selection Based on Environment
Choose different adapters for development and production.
function createApiClient(baseURL) {
const isNode = typeof window === 'undefined'
const isTest = process.env.NODE_ENV === 'test'
let adapter
if (isTest) {
adapter = createMockAdapter()
} else if (isNode && process.env.USE_HTTP2) {
adapter = createHttp2Adapter()
}
return axios.create({ baseURL, adapter })
}
Expected output: The client automatically selects the appropriate adapter: mock for tests, HTTP/2 for Node with flag, default HTTP/1.1 otherwise.
Common Mistakes
1. Using HTTP/2 adapter in the browser
HTTP/2 in browsers is handled automatically. Do not set a custom HTTP/2 adapter in browser code.
2. Ignoring session reuse window
HTTP/2 sessions have timeouts. Implement session management to recreate sessions before they expire.
3. Forgetting error handling for stream errors
HTTP/2 streams can be reset by the server. Always handle stream errors and retry logic.
4. Not handling GOAWAY frames
The server may send GOAWAY to gracefully shut down a connection. Listen for this and create a new session.
5. Mixing HTTP/1.1 and HTTP/2 on the same adapter
An adapter handles one protocol version. Create separate instances for HTTP/1.1 and HTTP/2 clients.
Practice Questions
What is HTTP/2 multiplexing? Multiple requests and responses can be sent simultaneously over a single TCP connection without head-of-line blocking.
How does an Axios adapter work? An adapter is a function that receives the request config and returns a promise that resolves with a response-like object.
Why use a mock adapter in tests? To test request/response handling without making real network calls, making tests faster and more reliable.
Can Axios use HTTP/2 in browsers? Browsers handle HTTP/2 internally. Custom adapters are only useful in Node.js.
What is the main benefit of HTTP/2 for API clients? Connection reuse and multiplexing reduce latency when making many requests to the same server.
Challenge
Build an adapter that automatically switches between HTTP/1.1 and HTTP/2 based on server capability detection, with automatic fallback if the server does not support HTTP/2.
FAQ
Mini Project
Build a dual-adapter API client that uses HTTP/2 when available with automatic fallback to HTTP/1.1. Measure and log the performance difference between the two protocols.
import http2 from 'http2'
async function createHttp2Adapter() {
const session = http2.connect('https://api.example.com')
return async function adapter(config) {
return new Promise((resolve, reject) => {
try {
const req = session.request({
':path': config.url,
':method': config.method.toUpperCase()
})
let data = ''
req.on('data', chunk => data += chunk)
req.on('end', () => resolve({
data: JSON.parse(data),
status: 200,
statusText: 'OK',
headers: {},
config
}))
req.on('error', reject)
req.end()
} catch (err) {
reject(err)
}
})
}
}
async function compareProtocols() {
const endpoints = ['/api/users', '/api/products', '/api/orders', '/api/settings']
// HTTP/1.1 baseline
let start = Date.now()
await Promise.all(endpoints.map(url => axios.get('https://api.example.com' + url)))
console.log('HTTP/1.1 total:', Date.now() - start, 'ms')
// HTTP/2
start = Date.now()
const h2Adapter = await createHttp2Adapter()
await Promise.all(endpoints.map(url => axios.get('https://api.example.com' + url, { adapter: h2Adapter })))
console.log('HTTP/2 total:', Date.now() - start, 'ms')
}
What's Next
Build a complete application:
| Tutorial | What You'll Learn |
|---|---|
| Axios Project | Build a complete application with all Axios features |
| Interceptors and Error Handling | Advanced interceptor patterns and error strategies |
Related topics: Node.js HTTP/2 module, protocol buffers and HTTP optimization.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro