Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - cypherpulse/go-waitlist-server: A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin · GitHub
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - cypherpulse/go-waitlist-server: A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin · GitHub
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - cypherpulse/go-waitlist-server: A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin · GitHub
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - cypherpulse/go-waitlist-server: A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin · GitHub
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - cypherpulse/go-waitlist-server: A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin · GitHub
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - cypherpulse/go-waitlist-server: A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin · GitHub
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - cypherpulse/go-waitlist-server: A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin · GitHub
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Waitlist Backend (Go + MongoDB)

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin. This README is intentionally detailed so you can learn how a clean Go backend is structured and why each layer exists.

What you will learn

  • How to structure a Go backend with clear separation of concerns.
  • How to build HTTP handlers with net/http and middleware chains.
  • How to validate inputs and return consistent JSON responses.
  • How to use the MongoDB Go driver with connection pooling and indexes.
  • How to make services resilient with timeouts, rate limits, and body limits.
  • How to configure apps with environment variables and .env files.

Requirements

  • Go 1.26+
  • MongoDB (local or Atlas)

Quick start

Create a .env file at the repo root (already supported):

MONGO_URI=mongodb://localhost:27017
DB_NAME=waitlist
ALLOWED_ORIGINS=http://localhost:3000

Run the API:

go run ./cmd/api

API summary

  • POST /api/waitlist stores a submission in MongoDB.
  • GET /health checks server and MongoDB connectivity.

Success response:

{ "status": "ok", "message": "Added to waitlist" }

Error response:

{ "status": "error", "message": "Invalid email" }

Project layout (modern and easy to understand)

This structure keeps transport concerns separate from business logic and data access.

waitlistbackend/
cmd/
api/
main.go
internal/
config/
config.go
repository/
models.go
waitlist_repository.go
service/
waitlist_service.go
transport/
http/
handlers/
errors.go
health.go
json.go
waitlist.go
middleware/
cors.go
middleware.go
ratelimit.go
request.go
validation/
validation.go
app.http
go.mod
README.md

File-by-file guide

Entry point

  • cmd/api/main.go
    • Bootstraps the app: loads config, connects to MongoDB, wires handlers, and starts the HTTP server.
    • Builds the middleware chain (CORS, body limit, timeout, rate limit, logging).
    • Handles graceful shutdown and ensures MongoDB disconnect on exit.

Configuration

  • internal/config/config.go
    • Loads environment variables from the shell or a .env file.
    • Supports ENV_FILE override and tries .env in current and parent directories.
    • Parses typed config values (durations, ints, floats) with sensible defaults.

HTTP transport (handlers)

HTTP transport (middleware)

Business logic

  • internal/service/waitlist_service.go
    • Validates required fields and email format.
    • Creates a waitlist record with CreatedAt and delegates storage to the repository.
    • Converts repository errors to service-level errors.

Data access

Validation utilities

Testing requests

  • app.http
    • Ready-to-run HTTP examples for VS Code REST client.

Request flow (handlers -> service -> repository)

  1. POST /api/waitlist hits the waitlist handler.
  2. The handler parses JSON and validates the payload.
  3. The service enforces business rules and prepares a record.
  4. The repository inserts into MongoDB and enforces uniqueness.
  5. The handler returns a JSON response.

This layered flow makes it easy to test each piece independently and scale the app later.

Configuration reference

All settings can come from shell env or .env. Values are read at startup.

  • MONGO_URI (required)
  • DB_NAME (required)
  • ALLOWED_ORIGINS (required, comma-separated)
  • PORT (default: 8080)
  • REQUEST_TIMEOUT (default: 5s)
  • MAX_BODY_BYTES (default: 65536)
  • RATE_LIMIT_RPS (default: 5)
  • RATE_LIMIT_BURST (default: 10)
  • MONGO_MAX_POOL_SIZE (default: 100)
  • ENV_FILE (optional path to a specific .env file)

Local development tips

  • Run from the repo root so .env is found automatically.
  • Use app.http to test requests without leaving VS Code.
  • If you run from cmd/api, config will still search parent directories for .env.

Deployment notes

  • For cloud deploys (Render, Fly, etc.), set env vars in the platform UI.
  • .env is intended for local development only.

Why not Gin?

This project uses net/http to show the fundamentals. Gin is great for rapid API development, but learning the standard library first gives you a deeper understanding of middleware, handlers, and request lifecycles. You can migrate to Gin later without changing the service or repository layers.

About

A production-ready waitlist backend that accepts frontend submissions, validates input, and persists data in MongoDB. It is designed for high concurrency and low latency, and it uses the standard net/http stack rather than Gin

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages