Recently, I’ve been working on adding code execution functionality to my project, something like an online compiler where users can write and run code directly in the browser. For that, I decided to explore Judge0, an awesome open-source code execution system.
I wanted to create a web app just like other code compilers, user can come and just write and run the code and just get the response back.
After making the mistake of trying to build my own code execution engine, this time I didn't fall for the pit (the pit I talk about in the previous blog). I got the idea to self-host judge 0 as it is an open source platform. With the help of Docker i will containerise it and deploy it on AWS, but at the same time I don't want to learn about Docker. May be in future I will learn how docker works, but since I’m still experimenting and wanted to get things running quickly, I looked for a simpler solution first.
While exploring, I found that Judge0 is also available as an API on RapidAPI. That meant I could skip all the setup and use it directly through API calls.
So for the beta version of my project (lexiCode Beta), I decided to go with this approach direct API calls to Judge0 via RapidAPI.
Below is the code where I am making an API call from next.js API route
export const POST = async (req) => {
const { source_code, language_id } = await req.json();
const API_URL = "https://judge0-ce.p.rapidapi.com/submissions/";
const headers = {
"X-RapidAPI-Key": "here comes the key",
"X-RapidAPI-Host": "judge0-ce.p.rapidapi.com",
"Content-Type": "application/json",
};
try {
const submissionResponse = await axios.post(
API_URL,
{ source_code, language_id },
{ headers }
);
const token = submissionResponse.data.token;
// Poll Judge0 for the result
const maxRetries = 5;
let retries = 0;
let judgeResponse;
while (retries < maxRetries) {
judgeResponse = await axios.get(`${API_URL}${token}`, { headers });
if (judgeResponse.data.status.id >= 3) {
break;
}
retries++;
await new Promise((resolve) => setTimeout(resolve, 2000));
}
if (retries === maxRetries) {
throw new Error("Exceeded maximum retries without success");
}
return new Response(JSON.stringify(judgeResponse.data), { status: 200 });
} catch (error) {
console.error("Error communicating with Judge0:", error.message);
return new Response(
JSON.stringify({
message: "Failed to compile code",
error: error.message,
}),
{ status: 500 }
);
}
};
For now I am only allowing two langauages for this application i.e., javascript and python. The problem that I am having with the response is the formatting, it's not what i want so right now i'm working on it.