go
44 lines · 6 steps
Building a protected admin area in Gin
A single route group applies Basic Auth once, then hangs a dashboard and user-management handlers off it.
Explained by
highlit
1package admin
2
3import (
4 "net/http"
5
6 "github.com/gin-gonic/gin"
7)
8
9func RegisterRoutes(r *gin.Engine, deps *Dependencies) {
10 admin := r.Group("/admin")
11 admin.Use(gin.BasicAuth(gin.Accounts{
12 deps.Config.AdminUser: deps.Config.AdminPassword,
13 }))
14
15 admin.GET("/", func(c *gin.Context) {
16 c.HTML(http.StatusOK, "admin/dashboard.tmpl", gin.H{
17 "user": c.MustGet(gin.AuthUserKey).(string),
18 "stats": deps.Metrics.Snapshot(),
19 })
20 })
21
22 admin.GET("/users", func(c *gin.Context) {
23 users, err := deps.Users.List(c.Request.Context())
24 if err != nil {
25 c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "failed to load users"})
26 return
27 }
28 c.JSON(http.StatusOK, users)
29 })
30
31 admin.POST("/users/:id/ban", func(c *gin.Context) {
32 id := c.Param("id")
33 if err := deps.Users.Ban(c.Request.Context(), id); err != nil {
34 c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{"error": err.Error()})
35 return
36 }
37 c.JSON(http.StatusOK, gin.H{"banned": id})
38 })
39
40 admin.DELETE("/cache", func(c *gin.Context) {
41 deps.Cache.Flush()
42 c.Status(http.StatusNoContent)
43 })
44}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Grouping routes lets you attach shared middleware like auth once instead of per-handler.
- 2Passing a dependencies struct keeps handlers testable and decoupled from global state.
- 3Aborting with a status on error keeps failures explicit and stops the handler chain cleanly.
Related explainers
typescript
import { registerLocaleData } from '@angular/common'; import localeFr from '@angular/common/locales/fr'; import localeFrExtra from '@angular/common/locales/extra/fr'; import localeDe from '@angular/common/locales/de';
Locale-aware bootstrapping in Angular
i18n
localization
dependency-injection
Intermediate
8 steps
go
package streaming import ( "bufio"
Streaming NDJSON logs over HTTP in Go
http-streaming
channels
select
Advanced
10 steps
typescript
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import * as Joi from 'joi';
Validating env config at boot in NestJS
configuration
schema-validation
environment-variables
Intermediate
8 steps
java
@Component @Converter public class EncryptedStringConverter implements AttributeConverter<String, String> {
Transparent column encryption in Spring & JPA
encryption
aes-gcm
jpa-converter
Advanced
10 steps
python
import time import uuid from django.utils.deprecation import MiddlewareMixin
Attaching per-request context in Django
middleware
request lifecycle
multi-tenancy
Intermediate
7 steps
go
package api import ( "crypto/sha256"
ETag conditional requests in Gin
http-caching
etag
conditional-requests
Intermediate
6 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/building-a-protected-admin-area-in-gin-explained-go-cf1a/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.