Skip to content

codewithdpk/narad

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

narad

A lightweight HTTP server framework built from scratch in Go using raw TCP connections. No external dependencies, just pure Go standard library.

Features

  • 🚀 Built from scratch using TCP sockets
  • 🛣️ Fast HTTP routing with support for path parameters
  • 📦 Simple and intuitive API
  • 🔄 JSON response helper
  • ⚡ Concurrent request handling with goroutines
  • 🎯 Pattern matching for dynamic routes

Installation

go get github.com/codewithdpk/narad

Quick Start

Here's a simple example to get you started:

package main

import (
	"github.com/codewithdpk/narad/internal/server"
)

func main() {
	// Create a new router
	r := server.New()

	// Define a simple route
	r.Handle("GET", "/", func(ctx *server.Context) {
		ctx.JSON(200, []byte(`{"message": "Hello, World!"}`))
	})

	// Start the server on port 8080
	r.Serve(":8080")
}

Run the example:

go run examples/basic_server.go

Test it with curl:

curl http://localhost:8080/

Usage Examples

Basic Routes

r := server.New()

// GET request
r.Handle("GET", "/api/users", func(ctx *server.Context) {
	ctx.JSON(200, []byte(`{"users": []}`))
})

// POST request
r.Handle("POST", "/api/users", func(ctx *server.Context) {
	ctx.JSON(201, []byte(`{"message": "User created"}`))
})

Path Parameters

Use :param syntax to capture dynamic path segments:

// Capture user ID from URL
r.Handle("GET", "/api/users/:id", func(ctx *server.Context) {
	userID := ctx.Params["id"]
	response := `{"id": "` + userID + `", "name": "User ` + userID + `"}`
	ctx.JSON(200, []byte(response))
})

// Multiple parameters
r.Handle("GET", "/api/posts/:postId/comments/:commentId", func(ctx *server.Context) {
	postID := ctx.Params["postId"]
	commentID := ctx.Params["commentId"]
	// Handle the request...
})

Test with:

curl http://localhost:8080/api/users/123

Context Object

The Context object provides access to request information:

type Context struct {
	Conn    net.Conn              // TCP connection
	Method  string                // HTTP method (GET, POST, etc.)
	Path    string                // Request path
	Version string                // HTTP version
	Headers map[string]string     // Request headers
	Body    string                // Request body
	Params  map[string]string     // Path parameters
}

Response Methods

// JSON response
ctx.JSON(200, []byte(`{"status": "ok"}`))

// Custom response with any content type
ctx.WriteResponse(200, "text/html", []byte("<h1>Hello</h1>"))

Testing the Server

Using curl

# GET request
curl http://localhost:8080/api/users

# GET with path parameter
curl http://localhost:8080/api/users/42

# POST request
curl -X POST http://localhost:8080/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "John Doe"}'

# Nested routes
curl http://localhost:8080/api/products/10/reviews

Using httpie

# GET request
http GET http://localhost:8080/api/users

# POST request
http POST http://localhost:8080/api/users name="John Doe"

Project Structure

narad/
├── cmd/
│   └── server/
│       └── main.go          # Original server implementation
├── examples/
│   └── basic_server.go      # Example server to get started
├── internal/
│   └── server/
│       ├── connection.go    # Connection handling and Context
│       ├── req.go           # Request parsing
│       ├── response.go      # Response structures
│       └── router.go        # Routing logic
└── README.md

How It Works

This HTTP server is built from the ground up without using Go's net/http package:

  1. TCP Listener: Creates a raw TCP socket listener
  2. Request Parsing: Manually parses HTTP request format
  3. Routing: Custom router with trie-based path matching
  4. Concurrent Handling: Each connection handled in a separate goroutine
  5. Response Building: Constructs HTTP responses following the HTTP/1.1 spec

API Reference

Router

New() *Router

  • Creates and returns a new router instance

Handle(method string, path string, handler Handler)

  • Registers a handler for the given HTTP method and path
  • Parameters:
    • method: HTTP method (GET, POST, PUT, DELETE, etc.)
    • path: URL path pattern (supports :param for dynamic segments)
    • handler: Function to handle the request

Serve(addr string)

  • Starts the HTTP server on the specified address
  • Parameter:
    • addr: Address to listen on (e.g., ":8080", "localhost:3000")

Context Methods

JSON(status int, data []byte)

  • Sends a JSON response
  • Parameters:
    • status: HTTP status code
    • data: JSON data as byte slice

WriteResponse(status int, contentType string, body []byte)

  • Sends a custom HTTP response
  • Parameters:
    • status: HTTP status code
    • contentType: Content-Type header value
    • body: Response body as byte slice

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is open source and available under the MIT License.

Author

Built with ❤️ by codewithdpk

About

A lightweight HTTP server framework built from scratch in Go using raw TCP connections. No external dependencies, just pure Go standard library.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages