The Evolution of My Quiz Web Application

Utkarsh MeshramUtkarsh Meshram
5 min read

Learning in Public: The Evolution of My Quiz Web Application

Hey everyone! I’m back with another update on my quiz web application journey. 🚀 If you've been following along, you know the goal is to build a platform that helps students prepare for their interviews. What started as an experiment with AI-generated questions has now taken a new direction, and I’m here to share the reasons, the challenges I’ve faced, and the progress so far. Let’s dive in!


Initial Objective: AI-Generated Questions for the Quiz App

Originally, my idea was to use AI services to generate quiz questions dynamically, thinking it would save time and offer a wide variety of content. I experimented with various APIs like OpenAI, Hugging Face, and Groq. Sounds futuristic, right? But things didn’t go as smoothly as planned. 😅

Here’s what went wrong: its the controller class for open ai api

  1.   Out of Credits: OpenAI gives $18 in free credits to early adopters. After that, it’s pay-to-use. I ran out of credits quicker than I anticipated. 💸package com.example.quizapp.Controller;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.client.RestTemplate;
    
      import com.example.quizapp.DTO.chatGPTRequest;
      import com.example.quizapp.DTO.chatGPTResponse;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.http.HttpStatus;
      import org.springframework.http.ResponseEntity;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
    
      @RestController
      @RequestMapping("/question")
      public class QuestionControler {
    
          @Autowired
          private RestTemplate restTemplate;
    
          @Value(value = "${openai.api.url}")
          String apiURL;
          @Value(value = "${openai.model}")
          String model;
    
          @SuppressWarnings("null")
          @GetMapping("/allQuestions")
          public ResponseEntity<String> getAllQuestions(@RequestParam String topic, @RequestParam String level) {
              try {
                  String prompt = "Generate 10 " + topic + " quiz questions having " + level + " difficulty, each with 4 options and specify the correct option in JSON format. Each question should include the question text, an array of options, and the correct answer. The JSON format should look like this: { 'questions': [ { 'question': 'What is ...?', 'options': ['A', 'B', 'C', 'D'], 'correct_answer': 'A' } ] }";
                  chatGPTRequest request = new chatGPTRequest(model, prompt);
    
                  ResponseEntity<chatGPTResponse> response = restTemplate.postForEntity(apiURL, request, chatGPTResponse.class);
    
                  if (response.getBody() != null && !response.getBody().getChoices().isEmpty()) {
                      return ResponseEntity.ok(response.getBody().getChoices().get(0).getMessage().getContent());
                  } else {
                      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to generate questions: Empty response from OpenAI");
                  }
              } catch (Exception e) {
                  return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to generate questions: " + e.getMessage());
              }
          }
      }
    
  2. Unreliable Output Formats: The AI models, while great for chatbots, weren’t delivering quiz questions in a steady JSON format. Sometimes the response included extra text or string formats that weren’t directly usable. I tried tweaking the prompts, but the results were inconsistent.

package com.example.quizapp.Config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.SimpleClientHttpRequestFactory;

@Configuration 
public class OpenAIConfig {

    @Value("${openai.api.key}")
    private String openApiKey;

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory());

        ClientHttpRequestInterceptor interceptor = (request, body, execution) -> {
            request.getHeaders().add("Authorization", "Bearer " + openApiKey);
            request.getHeaders().add("Content-Type", "application/json");
            return execution.execute(request, body);
        };

        restTemplate.getInterceptors().add(interceptor);
        return restTemplate;
    }
}

Facing Reality: Two Options

At this point, I had two paths ahead:

  1. Buy a subscription for a more reliable AI model. (Not ideal when you’re on a tight budget and learning in public. Plus, this was a side project meant to be free-to-use.)

  2. Manually feed questions into the system by adding an admin functionality. This way, I’d have full control over the quality and structure of the quiz content.

As much as I loved the idea of AI doing the heavy lifting, I decided to switch to manual question input for now. It felt more realistic and manageable, especially with my self-imposed deadlines. But don’t worry—I’m not abandoning the AI option. I’ll definitely revisit it in the future. For now, I just need to get this project done!


Current Progress: Manual Question Input + Admin Controls

Since I decided to go with manual question/answer entry, I’ve focused on adding admin functionality to manage the questions directly. This gives me full control over the content and ensures everything is structured properly for users.

Here’s a quick overview of what I’ve done so far:

  1. Admin Interface: I built an admin panel where questions can be added or updated manually.

  2. Endpoints Created: Using Spring Boot and PostgreSQL, I created several API endpoints for both normal users (to fetch quiz questions) and admins (to add or modify questions).

  3. User Interface: A basic front end is set up for users to take quizzes, with admin features accessible behind the scenes. It’s simple, but functional!

Here’s a sneak peek of the project so far:

What’s Next?

Even though I’ve shifted away from dynamic question generation for now, the learning has been immense. This challenge helped me get my hands dirty with:

  • Working with Spring Boot for building robust APIs.

  • Exploring PostgreSQL for database management.

  • Learning about the balance between relying on external APIs and building your own solutions.

I’m still planning to come back to the AI part once this project is complete, but for now, my focus is on delivering a stable, working product.

If you’re curious to see my code (and where I struggled), feel free to check out my GitHub repo: https://github.com/utkarsh125msh
Follow me on X : https://x.com/6Meshram93984


Final Thoughts

This project is teaching me a lot, and I’m loving the challenge—even if things didn’t go as originally planned. At the end of the day, that’s what learning in public is all about: adapting, growing, and sharing the journey with others.

Stay tuned for more updates! Until then, keep exploring and building. 💻✨


Tags: #LearnInPublic #QuizApp #SpringBoot #PostgreSQL #BackendDevelopment #OpenAI

0
Subscribe to my newsletter

Read articles from Utkarsh Meshram directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Utkarsh Meshram
Utkarsh Meshram

Bio: 🚀 Software Developer | Learning in Public | Final year undergraduate at NIT raipur👨‍🎓 I’m passionate about backend development, especially in Java and Spring Boot. On a mission to learn, build, and share my journey through code. Currently working on a Quiz Web Application and documenting every step of the way. Join me as I explore new tech, solve problems, and grow with the community. Let’s learn and build together! 🌱