Networking Module
The Networking Module handles external API requests with built-in caching, rate limiting, and retry logic.
Overview
Making HTTP requests in Roblox can be challenging:
- Rate limits (500 requests per minute)
- No built-in caching
- No automatic retry logic
- Complex error handling
Raddish's Networking Module solves all of these problems.
HTTP Methods
GET Requests
lua
local Raddish = require(game.ReplicatedStorage.Raddish)
-- Basic GET request
local response = Raddish.HttpGet("https://api.example.com/data")
if response.Success then
print("Data:", response.Body)
else
warn("Failed:", response.StatusMessage)
endGET with Caching
lua
-- Cache response for 5 minutes
local response = Raddish.HttpGet("https://api.example.com/data", {
cache = true,
cacheTTL = 300 -- seconds
})
-- First call: Fetches from API (slow)
-- Next calls within 5 min: Returns from cache (instant!)GET with Headers
lua
local response = Raddish.HttpGet("https://api.example.com/protected", {
headers = {
["Authorization"] = "Bearer your-token-here",
["User-Agent"] = "RobloxGame/1.0"
}
})POST Requests
lua
-- Send JSON data
local response = Raddish.HttpPost("https://api.example.com/submit", {
username = "VerifiedHawaii",
score = 9999,
timestamp = os.time()
})
-- With custom headers
local response = Raddish.HttpPost("https://api.example.com/submit", {
data = "value"
}, {
headers = {
["Content-Type"] = "application/json",
["X-API-Key"] = "your-api-key"
}
})PUT Requests
lua
-- Update resource
local response = Raddish.HttpPut("https://api.example.com/users/123", {
name = "UpdatedName",
level = 100
})DELETE Requests
lua
-- Delete resource
local response = Raddish.HttpDelete("https://api.example.com/users/123", {
headers = {
["Authorization"] = "Bearer token"
}
})PATCH Requests
lua
-- Partial update
local response = Raddish.HttpPatch("https://api.example.com/users/123", {
level = 51 -- Only update level
})Batch Requests
Send multiple requests efficiently:
lua
local results = Raddish.HttpBatch({
{method = "GET", url = "https://api.example.com/user/1"},
{method = "GET", url = "https://api.example.com/user/2"},
{method = "GET", url = "https://api.example.com/user/3"},
{
method = "POST",
url = "https://api.example.com/log",
data = {event = "batch_complete"}
}
})
for i, result in ipairs(results) do
if result.Success then
print("Request", i, "succeeded:", result.Body)
else
print("Request", i, "failed:", result.StatusMessage)
end
endDiscord Webhooks
Simple Webhook
lua
local webhookUrl = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN"
Raddish.SendWebhook(webhookUrl, {
content = "Server started successfully!",
username = "Roblox Game Bot"
})Rich Embeds
lua
Raddish.SendDiscordWebhook(webhookUrl, {
title = "Player Achievement",
description = "VerifiedHawaii reached level 100!",
color = 0x00FF00, -- Green color
fields = {
{name = "Player", value = "VerifiedHawaii", inline = true},
{name = "Level", value = "100", inline = true},
{name = "Time Played", value = "50 hours", inline = true},
{name = "Server", value = game.JobId, inline = false}
},
footer = {text = "Achievement System"},
username = "Achievement Bot",
avatar_url = "https://example.com/avatar.png"
})Log System
lua
-- Create a logging system
local logWebhook = "https://discord.com/api/webhooks/YOUR_LOG_ID/TOKEN"
function logToDiscord(level, message, data)
local colors = {
INFO = 0x0099FF, -- Blue
WARN = 0xFFAA00, -- Orange
ERROR = 0xFF0000, -- Red
SUCCESS = 0x00FF00 -- Green
}
Raddish.SendDiscordWebhook(logWebhook, {
title = level .. " Log",
description = message,
color = colors[level] or 0x808080,
fields = data and {
{name = "Details", value = game:GetService("HttpService"):JSONEncode(data)}
} or {},
footer = {text = "Server: " .. game.JobId}
})
end
-- Usage
logToDiscord("ERROR", "Player exploit detected", {
player = "SuspiciousPlayer",
reason = "Impossible speed",
value = 500
})
logToDiscord("SUCCESS", "Server started", {
players = 0,
maxPlayers = 50
})REST API Helper
Simplified REST API calls with authentication:
lua
local baseUrl = "https://api.yourgame.com"
local apiKey = "your-secret-api-key"
-- GET with authentication
local userData = Raddish.APIRequest(baseUrl, "/users/123", {
method = "GET",
apiKey = apiKey,
cache = true,
cacheTTL = 600
})
-- POST with authentication
local createResponse = Raddish.APIRequest(baseUrl, "/users", {
method = "POST",
apiKey = apiKey,
data = {
username = "NewPlayer",
email = "player@example.com"
}
})
-- With custom token header
local response = Raddish.APIRequest(baseUrl, "/protected", {
method = "GET",
token = "custom-token",
headers = {
["X-Custom-Header"] = "value"
}
})Response Format
All HTTP methods return a consistent response format:
lua
{
Success = true/false,
StatusCode = 200,
StatusMessage = "OK",
Body = {...} -- Automatically parsed JSON or raw string
}Cache Management
Invalidate Cache
lua
-- Invalidate specific URL cache
Raddish.InvalidateHttpCache("https://api.example.com/data")
-- Clear all HTTP cache
local clearedCount = Raddish.ClearHttpCache()
print("Cleared", clearedCount, "cached responses")Check Network Stats
lua
local stats = Raddish.GetNetworkStats()
print("Queue size:", stats.queueSize)
print("Requests this window:", stats.requestsThisWindow)
print("Max per window:", stats.maxRequestsPerWindow)
print("Cache size:", stats.cacheSize)Rate Limiting
The module automatically handles rate limiting:
lua
-- If rate limit is reached, requests are queued
local response = Raddish.HttpGet("https://api.example.com/data")
if response.StatusCode == 429 then
print("Rate limited - request was queued")
end
-- Manually queue a request
local requestId = Raddish.QueueRequest("GET", "https://api.example.com/data")
print("Queued request:", requestId)Retry Logic
Failed requests are automatically retried with exponential backoff:
lua
-- Configuration (in NetworkingModule.lua)
local MAX_RETRIES = 3
local RETRY_DELAY = 2 -- Initial delay in seconds
-- Attempts:
-- 1st: Immediate
-- 2nd: After 2 seconds
-- 3rd: After 4 seconds
-- Final: Return errorUse Cases
Analytics Tracking
lua
function trackEvent(eventName, eventData)
Raddish.HttpPost("https://analytics.yourgame.com/events", {
event = eventName,
data = eventData,
timestamp = os.time(),
serverId = game.JobId,
placeId = game.PlaceId
}, {
headers = {
["Authorization"] = "Bearer " .. analyticsKey
}
})
end
-- Track player join
game.Players.PlayerAdded:Connect(function(player)
trackEvent("player_joined", {
userId = player.UserId,
username = player.Name,
accountAge = player.AccountAge
})
end)External Inventory System
lua
function syncInventory(player)
local response = Raddish.APIRequest(
"https://inventory.yourgame.com",
"/player/" .. player.UserId .. "/items",
{
method = "GET",
apiKey = inventoryApiKey,
cache = true,
cacheTTL = 300
}
)
if response.Success then
local items = response.Body.items
-- Store in Raddish cache
for _, item in ipairs(items) do
Raddish.HSet("inventory:" .. player.UserId, item.id, item.quantity)
end
print("Synced", #items, "items for", player.Name)
end
end
-- Update external inventory
function giveItem(player, itemId, quantity)
-- Update local cache first
Raddish.HSet("inventory:" .. player.UserId, itemId, quantity)
-- Sync with external API
Raddish.APIRequest(
"https://inventory.yourgame.com",
"/player/" .. player.UserId .. "/items",
{
method = "POST",
apiKey = inventoryApiKey,
data = {
itemId = itemId,
quantity = quantity
}
}
)
endServer Status Monitoring
lua
local monitoringUrl = "https://monitoring.yourgame.com"
function reportServerStatus()
local stats = {
serverId = game.JobId,
placeId = game.PlaceId,
players = #game.Players:GetPlayers(),
maxPlayers = game.Players.MaxPlayers,
memory = game:GetService("Stats"):GetTotalMemoryUsageMb(),
uptime = workspace.DistributedGameTime,
timestamp = os.time()
}
Raddish.HttpPost(monitoringUrl .. "/server-status", stats, {
headers = {
["X-Server-Key"] = "monitoring-key"
}
})
end
-- Report every 30 seconds
task.spawn(function()
while true do
reportServerStatus()
task.wait(30)
end
end)External Leaderboard
lua
function syncLeaderboard()
-- Fetch from external API
local response = Raddish.HttpGet("https://api.yourgame.com/leaderboard/top100", {
cache = true,
cacheTTL = 60 -- Cache for 1 minute
})
if response.Success then
-- Update local sorted set
for _, entry in ipairs(response.Body.players) do
Raddish.ZAdd("leaderboard:global", entry.score, entry.userId)
end
end
end
-- Sync every minute
task.spawn(function()
while true do
syncLeaderboard()
task.wait(60)
end
end)
-- Update external leaderboard when player scores
function updateScore(player, newScore)
-- Update local
Raddish.ZAdd("leaderboard:global", newScore, player.UserId)
-- Update external
Raddish.HttpPost("https://api.yourgame.com/leaderboard/update", {
userId = player.UserId,
username = player.Name,
score = newScore
})
endPayment Verification
lua
function verifyPurchase(player, receiptInfo)
local response = Raddish.APIRequest(
"https://payment.yourgame.com",
"/verify",
{
method = "POST",
apiKey = paymentApiKey,
data = {
userId = player.UserId,
productId = receiptInfo.ProductId,
purchaseId = receiptInfo.PurchaseId,
timestamp = os.time()
}
}
)
if response.Success and response.Body.verified then
-- Grant product
grantProduct(player, receiptInfo.ProductId)
return Enum.ProductPurchaseDecision.PurchaseGranted
else
return Enum.ProductPurchaseDecision.NotProcessedYet
end
endError Handling
lua
local response = Raddish.HttpGet("https://api.example.com/data")
if not response.Success then
if response.StatusCode == 404 then
print("Resource not found")
elseif response.StatusCode == 429 then
print("Rate limited")
elseif response.StatusCode == 500 then
print("Server error")
else
warn("Request failed:", response.StatusMessage)
end
else
-- Success
print("Data:", response.Body)
endBest Practices
Always use caching for repeated requests
lua-- Good Raddish.HttpGet(url, {cache = true, cacheTTL = 300}) -- Bad (makes API call every time) Raddish.HttpGet(url)Handle errors gracefully
lualocal success, response = pcall(function() return Raddish.HttpGet(url) end) if success and response.Success then -- Process data endUse environment variables for API keys
lua-- Don't hardcode API keys! local apiKey = game:GetService("ServerStorage").Config.ApiKey.ValueMonitor rate limits
lualocal stats = Raddish.GetNetworkStats() if stats.requestsThisWindow > 80 then warn("Approaching rate limit!") end