Client Application Integration
Step-by-step guide for integrating RequestRocket into your client application
Client Application Integration
This guide will walk you through integrating RequestRocket into your client application with practical code examples in multiple languages.
Building a SaaS? Check out our SaaS Integration Guide to learn how to use RequestRocket as your integration platform for customers.
Prerequisites
Before integrating, ensure you have:
- A RequestRocket account
- An organisation (client) created
- A proxy configured with:
- Proxy credential
- Target credential
- Target API endpoint
Don't have a proxy yet? Follow the getting started guide →
Integration Steps
Get Your Proxy Details
From the RequestRocket dashboard:
- Navigate to your proxy
- Copy the Base URL
- Note your proxy credential type and value
Example Base URL:
https://us-east-1.requestrocket.com/api/prx_abc123Install HTTP Client
Choose an HTTP client for your programming language:
# Node.js - use built-in fetch or install axios
npm install axios# Python - install requests
pip install requests// Go - use net/http (built-in)
import "net/http"<!-- Java - add to pom.xml -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>Configure Your Application
Store your credentials securely:
// .env file
REQUESTROCKET_BASE_URL=https://us-east-1.requestrocket.com/api/prx_abc123
REQUESTROCKET_API_KEY=your-proxy-credential-here
// config.js
export const config = {
baseURL: process.env.REQUESTROCKET_BASE_URL,
apiKey: process.env.REQUESTROCKET_API_KEY
};# .env file
REQUESTROCKET_BASE_URL=https://us-east-1.requestrocket.com/api/prx_abc123
REQUESTROCKET_API_KEY=your-proxy-credential-here
# config.py
import os
from dotenv import load_dotenv
load_dotenv()
BASE_URL = os.getenv('REQUESTROCKET_BASE_URL')
API_KEY = os.getenv('REQUESTROCKET_API_KEY')// config.go
package main
import "os"
type Config struct {
BaseURL string
APIKey string
}
func LoadConfig() *Config {
return &Config{
BaseURL: os.Getenv("REQUESTROCKET_BASE_URL"),
APIKey: os.Getenv("REQUESTROCKET_API_KEY"),
}
}// Config.java
public class Config {
public static final String BASE_URL =
System.getenv("REQUESTROCKET_BASE_URL");
public static final String API_KEY =
System.getenv("REQUESTROCKET_API_KEY");
}Create Client Class
Build a reusable client:
// requestrocket.js
import { config } from './config.js';
class RequestRocketClient {
constructor() {
this.baseURL = config.baseURL;
this.apiKey = config.apiKey;
}
async request(method, path, data = null) {
const url = `${this.baseURL}${path}`;
const options = {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
}
};
if (data) {
options.body = JSON.stringify(data);
}
const response = await fetch(url, options);
// Check RequestRocket headers
const proxyCode = response.headers.get('requestrocket-proxy-code');
if (proxyCode === 'proxy-access-denied') {
throw new Error('Proxy authentication failed');
}
if (!response.ok) {
const error = await response.text();
throw new Error(`Request failed: ${response.status} - ${error}`);
}
return await response.json();
}
async get(path) {
return this.request('GET', path);
}
async post(path, data) {
return this.request('POST', path, data);
}
async put(path, data) {
return this.request('PUT', path, data);
}
async delete(path) {
return this.request('DELETE', path);
}
}
export default new RequestRocketClient();# requestrocket.py
import requests
from config import BASE_URL, API_KEY
class RequestRocketClient:
def __init__(self):
self.base_url = BASE_URL
self.api_key = API_KEY
self.session = requests.Session()
self.session.headers.update({
'Content-Type': 'application/json',
'Authorization': f'Bearer {self.api_key}'
})
def _request(self, method, path, **kwargs):
url = f"{self.base_url}{path}"
response = self.session.request(method, url, **kwargs)
# Check RequestRocket headers
proxy_code = response.headers.get('requestrocket-proxy-code')
if proxy_code == 'proxy-access-denied':
raise Exception('Proxy authentication failed')
response.raise_for_status()
return response.json()
def get(self, path, params=None):
return self._request('GET', path, params=params)
def post(self, path, data=None):
return self._request('POST', path, json=data)
def put(self, path, data=None):
return self._request('PUT', path, json=data)
def delete(self, path):
return self._request('DELETE', path)
client = RequestRocketClient()// client.go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type Client struct {
baseURL string
apiKey string
client *http.Client
}
func NewClient(cfg *Config) *Client {
return &Client{
baseURL: cfg.BaseURL,
apiKey: cfg.APIKey,
client: &http.Client{},
}
}
func (c *Client) Request(method, path string, body interface{}) (*http.Response, error) {
var bodyReader io.Reader
if body != nil {
jsonData, err := json.Marshal(body)
if err != nil {
return nil, err
}
bodyReader = bytes.NewBuffer(jsonData)
}
url := c.baseURL + path
req, err := http.NewRequest(method, url, bodyReader)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+c.apiKey)
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
// Check RequestRocket headers
if proxyCode := resp.Header.Get("requestrocket-proxy-code"); proxyCode == "proxy-access-denied" {
return nil, fmt.Errorf("proxy authentication failed")
}
return resp, nil
}
func (c *Client) Get(path string, result interface{}) error {
resp, err := c.Request("GET", path, nil)
if err != nil {
return err
}
defer resp.Body.Close()
return json.NewDecoder(resp.Body).Decode(result)
}
func (c *Client) Post(path string, body, result interface{}) error {
resp, err := c.Request("POST", path, body)
if err != nil {
return err
}
defer resp.Body.Close()
return json.NewDecoder(resp.Body).Decode(result)
}// RequestRocketClient.java
import okhttp3.*;
import com.google.gson.Gson;
import java.io.IOException;
public class RequestRocketClient {
private final String baseURL;
private final String apiKey;
private final OkHttpClient client;
private final Gson gson;
public RequestRocketClient() {
this.baseURL = Config.BASE_URL;
this.apiKey = Config.API_KEY;
this.client = new OkHttpClient();
this.gson = new Gson();
}
private Response request(String method, String path, Object body) throws IOException {
String url = baseURL + path;
Request.Builder builder = new Request.Builder()
.url(url)
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + apiKey);
if (body != null) {
String json = gson.toJson(body);
RequestBody requestBody = RequestBody.create(
json,
MediaType.parse("application/json")
);
builder.method(method, requestBody);
} else {
builder.method(method, null);
}
Response response = client.newCall(builder.build()).execute();
String proxyCode = response.header("requestrocket-proxy-code");
if ("proxy-access-denied".equals(proxyCode)) {
throw new IOException("Proxy authentication failed");
}
if (!response.isSuccessful()) {
throw new IOException("Request failed: " + response.code());
}
return response;
}
public <T> T get(String path, Class<T> responseType) throws IOException {
Response response = request("GET", path, null);
String json = response.body().string();
return gson.fromJson(json, responseType);
}
public <T> T post(String path, Object body, Class<T> responseType) throws IOException {
Response response = request("POST", path, body);
String json = response.body().string();
return gson.fromJson(json, responseType);
}
}Make Your First Request
Test your integration:
# Example: Fetch user data
curl -X GET "https://us-east-1.requestrocket.com/api/prx_abc123/users/123" \
-H "Authorization: Bearer your-proxy-credential-here" \
-H "Content-Type: application/json"
# Example: Create new user
curl -X POST "https://us-east-1.requestrocket.com/api/prx_abc123/users" \
-H "Authorization: Bearer your-proxy-credential-here" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@example.com"
}'
# Example: Update user
curl -X PUT "https://us-east-1.requestrocket.com/api/prx_abc123/users/123" \
-H "Authorization: Bearer your-proxy-credential-here" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Doe"
}'
# Example: Delete user
curl -X DELETE "https://us-east-1.requestrocket.com/api/prx_abc123/users/123" \
-H "Authorization: Bearer your-proxy-credential-here"// Example: Fetch user data
import client from './requestrocket.js';
async function getUser(userId) {
try {
const user = await client.get(`/users/${userId}`);
console.log('User:', user);
return user;
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
// Example: Create new user
async function createUser(userData) {
try {
const user = await client.post('/users', userData);
console.log('Created user:', user);
return user;
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
// Usage
await getUser('123');
await createUser({ name: 'John Doe', email: 'john@example.com' });# Example: Fetch user data
from requestrocket import client
def get_user(user_id):
try:
user = client.get(f'/users/{user_id}')
print(f'User: {user}')
return user
except Exception as e:
print(f'Error: {e}')
raise
# Example: Create new user
def create_user(user_data):
try:
user = client.post('/users', user_data)
print(f'Created user: {user}')
return user
except Exception as e:
print(f'Error: {e}')
raise
# Usage
user = get_user('123')
new_user = create_user({
'name': 'John Doe',
'email': 'john@example.com'
})// main.go
package main
import (
"fmt"
"log"
)
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func main() {
cfg := LoadConfig()
client := NewClient(cfg)
// Get user
var user User
err := client.Get("/users/123", &user)
if err != nil {
log.Fatal(err)
}
fmt.Printf("User: %+v\n", user)
// Create user
newUser := User{
Name: "John Doe",
Email: "john@example.com",
}
var created User
err = client.Post("/users", newUser, &created)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created: %+v\n", created)
}// Main.java
public class Main {
public static void main(String[] args) {
RequestRocketClient client = new RequestRocketClient();
try {
// Get user
User user = client.get("/users/123", User.class);
System.out.println("User: " + user);
// Create user
User newUser = new User("John Doe", "john@example.com");
User created = client.post("/users", newUser, User.class);
System.out.println("Created: " + created);
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}Error Handling
Implement robust error handling:
Check Response Headers
# Check response headers with verbose output
curl -v -X GET "https://us-east-1.requestrocket.com/api/prx_abc123/users/123" \
-H "Authorization: Bearer your-proxy-credential-here" \
-H "Content-Type: application/json"
# Look for these headers in the response:
# < requestrocket-proxy-code: proxy-access-granted
# < requestrocket-proxy-message: Access granted
# Check only headers (no body)
curl -I "https://us-east-1.requestrocket.com/api/prx_abc123/users/123" \
-H "Authorization: Bearer your-proxy-credential-here"async function makeRequest(path) {
const response = await fetch(proxyUrl + path, options);
const proxyCode = response.headers.get('requestrocket-proxy-code');
const proxyMessage = response.headers.get('requestrocket-proxy-message');
if (proxyCode === 'proxy-access-denied') {
throw new Error(`Authentication failed: ${proxyMessage}`);
}
if (proxyCode === 'proxy-access-granted' && !response.ok) {
throw new Error(`Target API error: ${response.status}`);
}
return await response.json();
}def make_request(path):
response = requests.get(proxy_url + path, headers=headers)
proxy_code = response.headers.get('requestrocket-proxy-code')
proxy_message = response.headers.get('requestrocket-proxy-message')
if proxy_code == 'proxy-access-denied':
raise Exception(f'Authentication failed: {proxy_message}')
if proxy_code == 'proxy-access-granted' and not response.ok:
raise Exception(f'Target API error: {response.status_code}')
return response.json()func makeRequest(path string) (interface{}, error) {
resp, err := client.Request("GET", path, nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()
proxyCode := resp.Header.Get("requestrocket-proxy-code")
proxyMessage := resp.Header.Get("requestrocket-proxy-message")
if proxyCode == "proxy-access-denied" {
return nil, fmt.Errorf("authentication failed: %s", proxyMessage)
}
if proxyCode == "proxy-access-granted" && resp.StatusCode >= 400 {
return nil, fmt.Errorf("target API error: %d", resp.StatusCode)
}
var result interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}public Object makeRequest(String path) throws IOException {
Response response = client.request("GET", path, null);
String proxyCode = response.header("requestrocket-proxy-code");
String proxyMessage = response.header("requestrocket-proxy-message");
if ("proxy-access-denied".equals(proxyCode)) {
throw new IOException("Authentication failed: " + proxyMessage);
}
if ("proxy-access-granted".equals(proxyCode) && !response.isSuccessful()) {
throw new IOException("Target API error: " + response.code());
}
return gson.fromJson(response.body().string(), Object.class);
}Implement Retry Logic
async function fetchWithRetry(url, options, maxRetries = 3) {
const retryableCodes = [408, 429, 500, 502, 503, 504];
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (response.ok || !retryableCodes.includes(response.status)) {
return response;
}
// Calculate backoff delay
const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
await new Promise(resolve => setTimeout(resolve, delay));
} catch (error) {
if (attempt === maxRetries - 1) throw error;
}
}
}Common Integration Patterns
API Gateway Pattern
Use RequestRocket as your application's API gateway:
// Express.js example
app.use('/api/*', async (req, res) => {
const path = req.path.replace('/api', '');
try {
const result = await client.request(
req.method,
path,
req.body
);
res.json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
});Microservices Communication
Route between microservices:
class ServiceClient {
constructor(serviceName) {
this.client = new RequestRocketClient();
this.serviceName = serviceName;
}
async call(endpoint, method = 'GET', data = null) {
const path = `/${this.serviceName}${endpoint}`;
return await this.client.request(method, path, data);
}
}
const userService = new ServiceClient('users');
const paymentService = new ServiceClient('payments');
// Usage
const user = await userService.call('/profile/123');
const payment = await paymentService.call('/charge', 'POST', chargeData);Webhook Forwarding
Use Async API for reliable webhook delivery:
async function forwardWebhook(webhookData) {
const asyncURL = proxyBaseURL.replace('/api/', '/async/');
const response = await fetch(asyncURL + '/webhooks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify(webhookData)
});
const { requestId } = await response.json();
console.log('Webhook queued:', requestId);
return requestId;
}Testing Your Integration
Unit Tests
// Jest example
import client from './requestrocket';
jest.mock('./requestrocket');
test('fetches user successfully', async () => {
const mockUser = { id: '123', name: 'John' };
client.get.mockResolvedValue(mockUser);
const user = await getUser('123');
expect(user).toEqual(mockUser);
expect(client.get).toHaveBeenCalledWith('/users/123');
});Integration Tests
test('proxy handles authentication correctly', async () => {
const response = await fetch(proxyURL + '/test', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
expect(response.headers.get('requestrocket-proxy-code'))
.toBe('proxy-access-granted');
});Production Considerations
1. Rate Limiting
Monitor and handle rate limits:
class RateLimitedClient extends RequestRocketClient {
constructor() {
super();
this.requestCount = 0;
this.resetTime = Date.now() + 60000;
}
async request(method, path, data) {
if (Date.now() > this.resetTime) {
this.requestCount = 0;
this.resetTime = Date.now() + 60000;
}
if (this.requestCount >= 100) {
const waitTime = this.resetTime - Date.now();
await new Promise(r => setTimeout(r, waitTime));
}
this.requestCount++;
return await super.request(method, path, data);
}
}2. Monitoring
Log requests for monitoring:
async function monitoredRequest(method, path, data) {
const start = Date.now();
try {
const result = await client.request(method, path, data);
logger.info('Request succeeded', {
method,
path,
duration: Date.now() - start,
status: 'success'
});
return result;
} catch (error) {
logger.error('Request failed', {
method,
path,
duration: Date.now() - start,
error: error.message
});
throw error;
}
}3. Caching
Implement response caching:
class CachedClient extends RequestRocketClient {
constructor() {
super();
this.cache = new Map();
}
async get(path, ttl = 300000) {
const cached = this.cache.get(path);
if (cached && Date.now() < cached.expiry) {
return cached.data;
}
const data = await super.get(path);
this.cache.set(path, {
data,
expiry: Date.now() + ttl
});
return data;
}
}Need help? Contact support or check our community forums for assistance.