Reetu Raj

#5 Code execution System

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.

The Plan

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.

Judge0 on RapidAPI

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 }
    );
  }
};

Issue to fix

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.