Introduction To Using HTTP Get Requests And Creating Your Own APIs

Hi there Devforum! I’ve recently been experimenting with HTTP requests, and want to help newer developers with getting to know the basics. So, I’ll be teaching you how to do just that, in the simplest way possible. It is important to note that HTTP requests can sometimes open backdoors and other dangerous exploits to not just your games, but also the server that the API, or whatever you choose to do with the HTTP requests.

In this tutorial, you will learn:

  • How to setup your game for HTTP requests
  • How to make a HTTP get request from a script
  • Use an API with an HTTP get request
  • Create your own API in Node JS

Useful links:
Roblox HTTP Library Documentation
HTTP Overview
HTTP Overview (Video)
What Is An API? (Video)
Node JS Tutorial

To allow HTTP requests to be used in your game, you’ll have to turn on one setting.

  1. Go to FILEGame Settings...
  2. Select Security
  3. Enable Allow HTTP Requests
    You will get a warning that says, “Enabling security bypasses may make your experience vulnerable to third party attacks.” Don’t worry about this for now, but if you plan on using HTTP requests for security, you will have to make sure your system for making and receiving them is secure.

Now that we can make HTTP get requests, let’s learn the basics.

Create a new Script in ServerScriptService and call it whatever you want.
Once you’re inside of that script, replace the code that’s already there with:

local http = game.HttpService

or:

local http = game:GetService("HttpService")

This will reference the HttpService with a variable, and is what we’ll use for making our HTTP requests.

To create an HTTP get request, we can use the GetAsync() function.
Although it has 3, we will only be using one of the parameters this function can take. This parameter is the URL, which is a string formatted like https://your-website-if-you-have-one.com. If the website uses http, or for whatever reason you don’t want to use https, you can write it like http://your-website-if-you-have-one.com. (You can’t miss out the https:// or http:// !)
I also recommend keeping your URL in a variable.

This is what a basic get request looks like:

local http = game.HttpService

local url = "https://google.com"

local res = http:GetAsync(url)
-- "res" is short for result, and "req" is short for request, remember this for later.

print(res)

With a normal website, a get request will return the HTML code for it.
Usually when using an Async (Asynchronous) function in Roblox, you will use what is called a Pcall. Pcalls contain errors to stop your script from breaking if you get one.
Here is what that same script looks like with a Pcall:

local http = game.HttpService

local url = "https://google.com"

local success, errormsg = pcall(function()
	res = http:GetAsync(url)
	-- The "res" variable can no longer be local if we want to use it outside of the Pcall, as a Pcall is a function.
end)
-- The first variable in a Pcall is a boolean, and indicates whether there was an error inside of the Pcall. We will call it "success".
-- The second variable in a Pcall is a string; if there is an error, it will be the error message. We will call it "errormsg", as "error" is already taken by a built-in function.

if success then
	print(res)
else
	print(errormsg)
end
-- If the Pcall executed successfully, we will print the result of the HTTP get request. If it didn't, we will print the reason for it failing.

Now that you know how to make an HTTP get request, let’s use it to get a result from an API

For this example, I’ll be using the 8Ball API (https://www.eightballapi.com)
But, before we use an API, it’s useful to understand what a query is in a URL.
When you do a google search, you can see a whole lot of gibberish in the url. But if we remove of it, we get:

https://www.google.com/search?q=hello+world&safe=active

When we separate the parts of this URL, we get:

  • https:// - This shows that it’s a URL
  • www - The subdomain for google
  • .google - The domain for google
  • .com - The extension for the domain
  • /search - The subfolder
  • ? - This indicates the start of the first query
  • q=hello+world - The first query; its name is “q”, and its value is “hello+world”.
  • & - This indicates the start of the second query, and is used to separate all other queries
  • safe=active - The same as q=hello+world, but the name is “safe”, and the value is “active”. I believe this references Safe Search.

Now that you (hopefully) understand queries, let’s go onto the API’s website.
If you scroll down to the “Build your own API query”, you should be able to see something like this:

As you can see, the API has three settings that you can change.
The first is the question; and will change the “question” query in the URL it gives below.
The second is whether it is biased or not; and will tell the server to have a “biased” reply.
And the third is whether it is lucky or not. Like the “biased” input, it uses the question to determine the answer.

If we set the question to “Is BriefYayyayyay cool?”, enable the “biased” option, and keep the “lucky” option disabled, we will end up with:

https://eightballapi.com/api/biased?question=Is+BriefYayyayyay+cool?&lucky=false

When we separate the URL like with the google search, we get:

  • https://
  • eightballapi
  • .com
  • /api
  • ?
  • question=Is+BriefYayyayyay+cool?
  • &
  • lucky=false

How about we use a Roblox script to get the answer?
Although it is generally better to use a Pcall, we’ll keep it out just this once.

local http = game.HttpService

local url = "https://eightballapi.com/api/biased?question=Is+BriefYayyayyay+cool?&lucky=false"

local res = http:GetAsync(url)

print(res)

If we run this script, you should get something along the lines of this in the console:

17:06:52.154  {"reading":"My sources say no.","question":"Is BriefYayyayyay cool?","sentiment":{"score":1,"comparative":0.3333333333333333,"calculation":[{"cool":1}],"tokens":["is","briefyayyayyay","cool"],"words":["cool"],"positive":["cool"],"negative":[]},"lucky":"false"}  -  Server - Script:5

This is quite hard to read, so we’ll use the HTTP library’s JSONDecode function.

http:JSONDecode(res)

Open the dictionary / table (whatever you want to call it) with the arrow on the left.

img2

From this, we can tell that the answer is called “reading”, so this will be our final script:

local http = game.HttpService

local url = "https://eightballapi.com/api/biased?question=Is+BriefYayyayyay+cool?&lucky=false"

local res = http:GetAsync(url)

print(http:JSONDecode(res)["reading"])

And this is what the result would look like:

17:19:03.867  My reply is no.  -  Server - Script:7

:cry:

Now that we know the basics of HTTP get requests and APIs, let’s code one ourselves using Node JS
Do note that this will be a lot easier if you are familiar with Node JS / JavaScript

APIs have to be hosted on a web address, which is why we will use Replit. Replit offers free hosting. (But unfortunately, it doesn’t stay online forever)

Once you’ve created a Replit account, create a new Node JS “Repl”. You can do this from the homepage by clicking the “Create Repl” button on the top left of your screen, and searching for “Node JS” for the template. Give it a name and create it.

Now you should be shown an empty place to code in the centre of your screen. To host the API, we’ll use Express JS.
This isn’t a tutorial on Node JS itself, so I won’t explain the basics. I’ve linked a good tutorial for it in the “Useful Links” part of this post, if you want to look at it.

Add this into the code box:

const express = require("express") // This is how you load modules in Node JS
const app = express() // Initialize Express

app.get("/", (req, res) => {
    res.send("Express JS server example") // The information it sends to someone who opens the website
})

app.listen(3000) // Listen on port 3000

While this code is running, it is up on the internet.
Replit should open a Webview on the top right, and you can open it in a new tab with this button:
img3

Copy the link of the website that it opens, and add it to your Roblox script.

local http = game.HttpService

local url = "https://repl-name.username.repl.co"

local res = http:GetAsync(url)

print(res)

Running this script, whatever you have in res.send() should be printed to the output.

Now let’s get a bit more advanced.
To get a query, we can put this inside of the app.get() function:

const express = require("express")
const app = express()

app.get("/", (req, res) => {
    if (req.query.code) { // Tell if there is a query called "code" in the URL
        console.log(req.query.code) // Log (print) the "code" query (Use req.query to get all of the queries)
        res.send(req.query.code) // Sends the "code" query to the client
    }
    else {
        res.send("no code noob")
    }
})

app.listen(3000)

Now if you run, the Roblox script, you will notice that you will get “no code noob” as a response. This is because we haven’t added a query to the URL.
To do this, add this to the end of your URL variable:

/?code=yourcodehere

Make sure that there is only one / after the repl.co!

Running this, you should get this (or something else if you replaced “yourcodehere”) in the output:

17:51:21.458  yourcodehere  -  Server - Script:7

Although I won’t walk you through making an entire API, these are the basics that you need to create one. (as well as some experience in Node JS / JavaScript)

Thanks for reading through all of this, I would love to see some of your own APIs, and if you have any questions, do ask!

6 Likes

wow this is amazing! good job man! ok that took time to read haha anyways can you tell me how many APIS you can make with it and why do we need to use Node.JS I am not very good in HTTP service and stuff. never really practiced it.

Nice tutorial! This does explain the basics well.

I use node.js w/ express.js on Replit to self-host my own proxy for sending requests to Roblox’s Web API via HttpService. It’s an excellent use case if you don’t want to use roproxy.

I also use express for my own private api.

Thanks, You don’t need Node JS specifically, other server-side languages like Python, C, Ruby, or anything that you can host a web server on also work similarly. (Maybe even Lua, but I’m not sure) I just used Node JS as I have a lot of practice with it.
You are however limited to just APIs that use text, but as long as it does it should be possible and work well with Roblox.
Basically everything with APIs is done outside of Roblox and can be done in just a few lines, so very good knowledge with HTTPService isn’t needed too much.

ohh ok ok thank you! I am now relaxed that using JS isnt neccessary as I dont have much practice with it. as I just tried it ONCE or twice? idr

Cool tutorial! Are you planning to do the same for the POST method?

I should add that you can use parameters as an alternative to queries:

app.get("/:code", (req, res) => {
    if (req.params.code) {
        console.log(req.params.code)
        res.send(req.params.code)
    }
    else {
        res.send("no code noob")
    }
})

Rather than the link being https://your-website-name.com/?code=your-code-here, it would be https://your-website-name.com/your-code-here

I’m not too sure, though it works quite similarly and I believe you can do the exact same thing with both GET and POST.

I wanted to add that this poses as a security risk. Especially if you are using this for a ranking script because anyone can just run game:GetService(“HttpService”):GetAsync(URL … “/ranker?userid=” … userId … “&rank=” … rank) in their console or anything similar but this is an example for using this code for ranking purposes. Someone I fired from my group didn’t have permissions to rank but he was able to find out my URL and used this code in his game to rank himself to a high rank and abuse his powers.

What is “this?” The security risk you described is a result of the developer not requiring an Authorization header or API key to validate requests. HttpService does not pose the risk you described.

Do you see them using any API keys? That is why I said it is a security risk.

The security risk is one imposed by the developer themselves, not by HttpService.

I agree, you need to do your checks on the server where the request is getting sent to before making the server respond to the request.