DEV Community

Alain Airom
Alain Airom

Posted on

Finally honored to meet Bob

My very first experience with IBM Bob Project

Introduction-What (who) is bob?

IBM Project Bob is an AI-powered software development partner designed to help developers ship quality software faster, with a focus on enterprise application modernization.

Key Features and Purpose

  • AI Development Partner: Bob is as an AI assistant that lives inside the Integrated Development Environment (IDE) to assist with asking, designing, debugging, and refactoring code.
  • Focus on Modernization: It is specifically built for enterprise needs, helping with modernization efforts like automated upgrades (e.g., Java 8 to 17) and framework migrations (e.g., Struts or JSF to React).
  • Enhanced Productivity: Internally, IBM developers who have tested Bob have reported significant productivity gains (averaging 45%) by reducing repetitive “grunt work.”
  • Contextual Understanding: Bob understands the developer’s intent, the codebase (repository), and enterprise security/compliance standards (like FedRAMP, HIPAA, and PCI).

Core Capabilities (among others…):

  • Chat in Editor: Allows developers to use natural language to ask questions, design, debug, and refactor code directly in their IDE.
  • Agentic Code Review: Goes beyond simple linting to flag issues early, explain its reasoning, and provide proactive, educational feedback.
  • Vulnerability & Secrets Detection: Surfaces security vulnerabilities and credential leaks as the developer codes, before they reach a pull request.

A word on Bob’s installation

The installation process for Project Bob proved to be notably straightforward. After executing the standard .dmg image and launching the application, Bob immediately offered to import existing settings from my preferred environment, VS Code. Accepting this integration instantly provided a complete, pre-configured VS Code environment, now seamlessly augmented with Bob’s powerful AI capabilities.

My very first Test — Code Part

Though my role is outside of IBM’s core product development teams, I was fortunate enough 🍀 to gain early access to Project Bob as a participant in a recent internal Bobathon (as in a hackathon). The moment the access email arrived last night, I eagerly jumped into testing. Frankly, the initial results — which I am about to share and describe in detail — were jaw-dropping and fundamentally changed my perspective on AI-assisted development.

To begin my evaluation, I deliberately used a rudimentary and poorly structured prompt, momentarily ignoring the best practices generously shared with me by one of Bob’s developers. Despite this intentional handicap, the resulting output was truly astonishing.

So let us dig into what I provided as input and what I got.

Build a Http server in go language, provide a dockerfile to build an image for the application and provide 
all necessary steps to deploy it to my minikube kubernetes cluster.
Enter fullscreen mode Exit fullscreen mode

The interaction began with Bob engaging me in a dynamic, multi-step conversation where it asked a series of probing questions. While the exact sequence of that dialogue was unfortunately not captured, the result it ultimately produced is as follows.

  • The whole structure of the project;
bob-project1/
├── main.go                 # Main HTTP server application
├── go.mod                  # Go module dependencies
├── Dockerfile              # Docker image configuration
├── .dockerignore          # Files to exclude from Docker build
├── k8s/
│   ├── deployment.yaml    # Kubernetes Deployment manifest
│   └── service.yaml       # Kubernetes Service manifest (NodePort)
├── Makefile               # Build and deployment automation
└── README.md              # This file
Enter fullscreen mode Exit fullscreen mode
  • While I am showcasing two representative files here, the full source code and all project materials have been uploaded to a GitHub repository. You can find the direct link to the repository in the designated ‘Links’ section.

  • The main go code 👨‍💻

package main

import (
 "context"
 "encoding/json"
 "log"
 "net/http"
 "os"
 "os/signal"
 "syscall"
 "time"
)

var (
 startTime = time.Now()
 version   = "1.0.0"
)

// Response structures
type HealthResponse struct {
 Status  string `json:"status"`
 Uptime  string `json:"uptime"`
 Version string `json:"version"`
}

type InfoResponse struct {
 Version   string    `json:"version"`
 Hostname  string    `json:"hostname"`
 Timestamp time.Time `json:"timestamp"`
 Message   string    `json:"message"`
}

type EchoResponse struct {
 Message   string    `json:"message"`
 Timestamp time.Time `json:"timestamp"`
}

type DataRequest struct {
 Name  string `json:"name"`
 Value string `json:"value"`
}

type DataResponse struct {
 Success   bool        `json:"success"`
 Data      DataRequest `json:"data"`
 Timestamp time.Time   `json:"timestamp"`
}

type ErrorResponse struct {
 Error     string    `json:"error"`
 Timestamp time.Time `json:"timestamp"`
}

// Middleware for logging requests
func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
 return func(w http.ResponseWriter, r *http.Request) {
  start := time.Now()
  log.Printf("[%s] %s %s", r.Method, r.URL.Path, r.RemoteAddr)
  next(w, r)
  log.Printf("Completed in %v", time.Since(start))
 }
}

// CORS middleware
func corsMiddleware(next http.HandlerFunc) http.HandlerFunc {
 return func(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Access-Control-Allow-Origin", "*")
  w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
  w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

  if r.Method == "OPTIONS" {
   w.WriteHeader(http.StatusOK)
   return
  }

  next(w, r)
 }
}

// Handler functions
func homeHandler(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")
 response := map[string]string{
  "message":   "Welcome to Go HTTP Server!",
  "version":   version,
  "endpoints": "/health, /api/info, /api/echo?message=<text>, /api/data (POST)",
 }
 json.NewEncoder(w).Encode(response)
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")
 uptime := time.Since(startTime)

 response := HealthResponse{
  Status:  "healthy",
  Uptime:  uptime.String(),
  Version: version,
 }

 json.NewEncoder(w).Encode(response)
}

func infoHandler(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")

 hostname, err := os.Hostname()
 if err != nil {
  hostname = "unknown"
 }

 response := InfoResponse{
  Version:   version,
  Hostname:  hostname,
  Timestamp: time.Now(),
  Message:   "Server information retrieved successfully",
 }

 json.NewEncoder(w).Encode(response)
}

func echoHandler(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")

 message := r.URL.Query().Get("message")
 if message == "" {
  w.WriteHeader(http.StatusBadRequest)
  json.NewEncoder(w).Encode(ErrorResponse{
   Error:     "Missing 'message' query parameter",
   Timestamp: time.Now(),
  })
  return
 }

 response := EchoResponse{
  Message:   message,
  Timestamp: time.Now(),
 }

 json.NewEncoder(w).Encode(response)
}

func dataHandler(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")

 if r.Method != http.MethodPost {
  w.WriteHeader(http.StatusMethodNotAllowed)
  json.NewEncoder(w).Encode(ErrorResponse{
   Error:     "Method not allowed. Use POST",
   Timestamp: time.Now(),
  })
  return
 }

 var req DataRequest
 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  w.WriteHeader(http.StatusBadRequest)
  json.NewEncoder(w).Encode(ErrorResponse{
   Error:     "Invalid JSON payload",
   Timestamp: time.Now(),
  })
  return
 }

 response := DataResponse{
  Success:   true,
  Data:      req,
  Timestamp: time.Now(),
 }

 w.WriteHeader(http.StatusCreated)
 json.NewEncoder(w).Encode(response)
}

func main() {
 // Get port from environment variable or use default
 port := os.Getenv("PORT")
 if port == "" {
  port = "8080"
 }

 // Setup routes with middleware
 http.HandleFunc("/", corsMiddleware(loggingMiddleware(homeHandler)))
 http.HandleFunc("/health", corsMiddleware(loggingMiddleware(healthHandler)))
 http.HandleFunc("/api/info", corsMiddleware(loggingMiddleware(infoHandler)))
 http.HandleFunc("/api/echo", corsMiddleware(loggingMiddleware(echoHandler)))
 http.HandleFunc("/api/data", corsMiddleware(loggingMiddleware(dataHandler)))

 // Create server
 server := &http.Server{
  Addr:         ":" + port,
  ReadTimeout:  15 * time.Second,
  WriteTimeout: 15 * time.Second,
  IdleTimeout:  60 * time.Second,
 }

 // Start server in a goroutine
 go func() {
  log.Printf("Starting server on port %s...", port)
  log.Printf("Server version: %s", version)
  log.Printf("Available endpoints:")
  log.Printf("  GET  /")
  log.Printf("  GET  /health")
  log.Printf("  GET  /api/info")
  log.Printf("  GET  /api/echo?message=<text>")
  log.Printf("  POST /api/data")

  if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
   log.Fatalf("Server failed to start: %v", err)
  }
 }()

 // Graceful shutdown
 quit := make(chan os.Signal, 1)
 signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
 <-quit

 log.Println("Shutting down server...")

 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
 defer cancel()

 if err := server.Shutdown(ctx); err != nil {
  log.Fatalf("Server forced to shutdown: %v", err)
 }

 log.Println("Server stopped gracefully")
}

// Made with Bob
Enter fullscreen mode Exit fullscreen mode
  • The sample Dockerfile
# Multi-stage build for smaller image size

# Stage 1: Build the Go application
FROM golang:1.21-alpine AS builder

# Set working directory
WORKDIR /app

# Copy go mod files
COPY go.mod ./

# Download dependencies
RUN go mod download

# Copy source code
COPY main.go ./

# Build the application
# CGO_ENABLED=0 for static binary
# -ldflags="-w -s" to reduce binary size
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags="-w -s" -o server .

# Stage 2: Create minimal runtime image
FROM alpine:latest

# Install ca-certificates for HTTPS requests (if needed)
RUN apk --no-cache add ca-certificates

# Create non-root user for security
RUN addgroup -g 1000 appuser && \
    adduser -D -u 1000 -G appuser appuser

# Set working directory
WORKDIR /home/appuser

# Copy binary from builder stage
COPY --from=builder /app/server .

# Change ownership to non-root user
RUN chown -R appuser:appuser /home/appuser

# Switch to non-root user
USER appuser

# Expose port 8080
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1

# Run the application
CMD ["./server"]
Enter fullscreen mode Exit fullscreen mode
  • Upon running the code, I encountered only one issue: a minor bug within the go.mod file, which I quickly corrected. Aside from this trivial edit, the application executed flawlessly and without any further difficulty.
module github.com/bob/go-http-server

go 1.21

require (
 // No external dependencies required for this basic HTTP server
 // All functionality uses Go standard library
)

// below there was a parasite character which generated an error!
//<!-- Made with Bob -->
Enter fullscreen mode Exit fullscreen mode

Architecture description of the provided code

One particularly handy feature is Bob’s ability to produce an instant, ready-to-use application architecture description, directly out of the box.

Seeking to test its extensibility, I went a step further and asked Bob to generate the application diagrams using the Mermaid syntax. The fact that it handled this request — beyond its built-in functionality — left me stunned. Bob generated a series of chart/diagram descriptions as shown below and updated the whole system architecture already provided!


# Go HTTP Server - Architecture Diagrams

This document contains comprehensive Mermaid diagrams illustrating the architecture and workflows of the Go HTTP Server project.

1. System Architecture

mermaid
graph TB
    subgraph "Client Layer"
        Client[Client/Browser]
    end

    subgraph "Kubernetes Cluster (Minikube)"
        Service[Service<br/>NodePort :30080]

        subgraph "Deployment (2 Replicas)"
            Pod1[Pod 1<br/>go-http-server]
            Pod2[Pod 2<br/>go-http-server]
        end
    end

    subgraph "Container"
        App[Go HTTP Server<br/>:8080]
        Health[Health Checks<br/>Liveness/Readiness]
    end

    Client -->|HTTP Request| Service
    Service -->|Load Balance| Pod1
    Service -->|Load Balance| Pod2
    Pod1 --> App
    Pod2 --> App
    App -.->|Probe| Health

    style Client fill:#e1f5ff
    style Service fill:#fff4e1
    style Pod1 fill:#e8f5e9
    style Pod2 fill:#e8f5e9
    style App fill:#f3e5f5
    style Health fill:#fce4ec


2. API Endpoints Flow

mermaid
graph LR
    Client[Client] --> Router{HTTP Router}

    Router -->|GET /| Home[Home Handler<br/>Welcome Message]
    Router -->|GET /health| Health[Health Handler<br/>Status & Uptime]
    Router -->|GET /api/info| Info[Info Handler<br/>Server Info]
    Router -->|GET /api/echo| Echo[Echo Handler<br/>Message Echo]
    Router -->|POST /api/data| Data[Data Handler<br/>JSON Processing]

    Home --> MW1[CORS Middleware]
    Health --> MW2[CORS Middleware]
    Info --> MW3[CORS Middleware]
    Echo --> MW4[CORS Middleware]
    Data --> MW5[CORS Middleware]

    MW1 --> Log1[Logging Middleware]
    MW2 --> Log2[Logging Middleware]
    MW3 --> Log3[Logging Middleware]
    MW4 --> Log4[Logging Middleware]
    MW5 --> Log5[Logging Middleware]

    Log1 --> Resp1[JSON Response]
    Log2 --> Resp2[JSON Response]
    Log3 --> Resp3[JSON Response]
    Log4 --> Resp4[JSON Response]
    Log5 --> Resp5[JSON Response]

    style Router fill:#fff4e1
    style Home fill:#e8f5e9
    style Health fill:#e8f5e9
    style Info fill:#e8f5e9
    style Echo fill:#e8f5e9
    style Data fill:#e8f5e9


3. Deployment Workflow

mermaid
sequenceDiagram
    participant Dev as Developer
    participant Docker as Docker
    participant Minikube as Minikube
    participant K8s as Kubernetes
    participant Pod as Pod

    Dev->>Docker: Build Image<br/>(multi-stage)
    Docker->>Docker: Stage 1: Build Go Binary
    Docker->>Docker: Stage 2: Create Alpine Image
    Docker-->>Dev: Image Ready

    Dev->>Minikube: eval $(minikube docker-env)
    Dev->>Docker: Build in Minikube
    Docker-->>Minikube: Image Available

    Dev->>K8s: kubectl apply deployment.yaml
    K8s->>Pod: Create 2 Replicas
    Pod->>Pod: Run Health Checks
    Pod-->>K8s: Ready

    Dev->>K8s: kubectl apply service.yaml
    K8s->>K8s: Create NodePort Service
    K8s-->>Dev: Service Available :30080

    Dev->>Minikube: minikube service go-http-server
    Minikube-->>Dev: Open Browser

4. Request Processing Flow

mermaid
flowchart TD
    Start([HTTP Request]) --> CORS{CORS<br/>Middleware}
    CORS -->|Add Headers| Log{Logging<br/>Middleware}
    Log -->|Log Request| Route{Route<br/>Handler}

    Route -->|/| Home[Home Handler]
    Route -->|/health| Health[Health Handler]
    Route -->|/api/info| Info[Info Handler]
    Route -->|/api/echo| Echo[Echo Handler]
    Route -->|/api/data| Data[Data Handler]

    Home --> JSON1[Encode JSON]
    Health --> JSON2[Encode JSON]
    Info --> JSON3[Encode JSON]
    Echo --> Valid{Valid<br/>Query?}
    Data --> Method{POST<br/>Method?}

    Valid -->|Yes| JSON4[Encode JSON]
    Valid -->|No| Err1[400 Error]

    Method -->|Yes| Parse{Valid<br/>JSON?}
    Method -->|No| Err2[405 Error]

    Parse -->|Yes| JSON5[201 Created]
    Parse -->|No| Err3[400 Error]

    JSON1 --> End([Response])
    JSON2 --> End
    JSON3 --> End
    JSON4 --> End
    JSON5 --> End
    Err1 --> End
    Err2 --> End
    Err3 --> End

    style Start fill:#e1f5ff
    style End fill:#e1f5ff
    style CORS fill:#fff4e1
    style Log fill:#fff4e1
    style Route fill:#f3e5f5


5. Docker Multi-Stage Build

mermaid
graph TB
    subgraph "Stage 1: Builder (golang:1.21-alpine)"
        S1[Copy go.mod] --> S2[Download Dependencies]
        S2 --> S3[Copy main.go]
        S3 --> S4[Build Static Binary<br/>CGO_ENABLED=0]
        S4 --> Binary[server binary<br/>~15MB]
    end

    subgraph "Stage 2: Runtime (alpine:latest)"
        R1[Install ca-certificates] --> R2[Create Non-Root User]
        R2 --> R3[Copy Binary from Builder]
        R3 --> R4[Set Permissions]
        R4 --> Final[Final Image<br/>~15MB]
    end

    Binary -.->|Copy| R3

    style Binary fill:#e8f5e9
    style Final fill:#e8f5e9


6. Application Lifecycle

mermaid
stateDiagram-v2
    [*] --> Starting: Server Start
    Starting --> Initializing: Load Config
    Initializing --> RegisteringRoutes: Setup Routes
    RegisteringRoutes --> ApplyingMiddleware: Add Middleware
    ApplyingMiddleware --> Running: Listen on Port 8080

    Running --> Processing: Incoming Request
    Processing --> Running: Response Sent

    Running --> ShuttingDown: SIGINT/SIGTERM
    ShuttingDown --> GracefulShutdown: Wait for Requests (30s)
    GracefulShutdown --> [*]: Server Stopped

    Processing --> Error: Request Failed
    Error --> Running: Log Error


Diagram Descriptions

1. System Architecture
Shows the complete deployment structure with Kubernetes components including the Service (NodePort), Deployment with 2 replicas, and the containerized Go application with health checks.

2. API Endpoints Flow
Illustrates how HTTP requests are routed to different handlers and processed through CORS and logging middleware layers.

3. Deployment Workflow
Sequence diagram showing the step-by-step process of building the Docker image and deploying to Kubernetes via Minikube.

4. Request Processing Flow
Detailed flowchart of how each HTTP request is processed, including validation, error handling, and response generation.

5. Docker Multi-Stage Build
Demonstrates the two-stage Docker build process that creates a minimal production image (~15MB).

6. Application Lifecycle
State diagram showing the server's lifecycle from startup through request processing to graceful shutdown.

---

**Generated for:** Go HTTP Server v1.0.0  
**Date:** 2025-12-14  
**Author:** Bob
Enter fullscreen mode Exit fullscreen mode

Below is one of the diagrams produced by Bob. To ensure accuracy, I independently validated Bob’s generated Mermaid description against my own manually constructed diagram for the codebase. The result was a perfect match, confirming the integrity of Bob’s output. 😜

Last but certainly not least, the project’s automatically generated README file is of remarkably high quality. It features a professional style, includes all the necessary detailed steps for setup and usage, and significantly enhances the project's immediate documentation.

🚀 Conclusion — The Transformative Value of Project Bob

Project Bob is not merely an incremental coding assistant; it represents an agentic, enterprise-grade AI partner that fundamentally shifts how high-quality software is delivered across the entire lifecycle.

  • For individual/enterprise Developers, it provides a stunning productivity boost (reported up to 45%) by tackling the tedious “grunt work” — from generating boilerplate code to translating natural language into complex implementation logic.
  • For Unit-Test Makers, Bob’s ability to understand deep repository context and developer intent means it can generate accurate, context-aware testing artifacts and documentation like README files and architecture diagrams (even in specialized formats like Mermaid), ensuring immediate quality and reducing validation overhead.
  • Finally, for DevSecOps and Application Modernization teams, the value is transformative: Bob integrates security by design through built-in vulnerability and secrets detection that "shifts left" directly into the IDE.

Furthermore, its specialized AI expertise accelerates massive modernization efforts, such as Java version upgrades (Java 8 to 17) and framework migrations (JSF to React), providing the performant, reliable tools necessary to maintain compliance, enhance governance, and drive critical enterprise transformation at unprecedented speed.

Thanks for reading!

Links

Top comments (0)