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

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages