# README
HTTP
Getting Started
Prerequisites
HTTP requests Go version 1.23 or above
Http key features:
- Router
- Response Types
body
,html
,json
,redirect
,download
andview
- Static Assets
- WebSocket
- Middleware
- Session
Getting with HTTP
Running HTTP server
Create a basic example create a go
file called main.go
and paste the below code.
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
func main() {
server := http.Server("127.0.0.1", 8080)
server.Route().Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.Html("<h1>Hello World</h1>")
})
fmt.Printf("Server running %s", server.Host())
server.Listen()
}
To run the code, use the go run
command, like:
$ go run main.go
Then open your favorite browser and visit 127.0.0.1:8080
you should see Hello World
Route Grouping
HTTP allows simple grouping of routes using Group
method
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
func main() {
server := http.Server("127.0.0.1", 8080)
server.Route().Group("api", func(route *http.Router) {
route.Group("products", func(route *http.Router) {
// Some routes
})
route.Group("invoices", func(route *http.Router) {
// Some routes
})
})
fmt.Printf("Server running %s", server.Host())
server.Listen()
}
Route Parameters
HTTP supports route params
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
func main() {
server := http.Server("127.0.0.1", 8080)
server.Route().Group("products", func(route *http.Router) {
route.Group("{product}", func(route *http.Router) {
route.Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.Body([]byte("<h1>Product: " + "</h1>")).Header("content-type", "text/html")
})
})
})
fmt.Printf("Server running %s", server.Host())
server.Listen()
}
Response Types
HTTP has several response type which are body
, html
, json
, redirect
, download
and view
which will be explained in the next section.
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
func main() {
server := http.Server("127.0.0.1", 8080)
server.Route().Group("/", func(route *http.Router) {
route.Get("body", func(req *http.Request, res *http.Response) *http.Response {
return res.Body([]byte("Hello World!!!")).Header("content-type", "text/plain; charset: utf-8")
})
route.Get("html", func(req *http.Request, res *http.Response) *http.Response {
return res.Html("<h1 style='color: green; font-size: 3em;'>Hello World!!!</h1>")
})
route.Get("view", func(req *http.Request, res *http.Response) *http.Response {
return res.View("hello_world")
})
route.Get("json", func(req *http.Request, res *http.Response) *http.Response {
return res.Json(struct {
Message string `json:"message"`
}{Message: "Hello World!!!"})
})
route.Get("redirect", func(req *http.Request, res *http.Response) *http.Response {
return res.Redirect("http://www.google.com/")
})
route.Get("download", func(req *http.Request, res *http.Response) *http.Response {
return res.Download("text/plain; charset=utf-8", "hello.txt", []byte("Hello World!!!"))
})
})
fmt.Printf("Server running %s", server.Host())
server.Listen()
}
Response View
HTTP view
response uses Scriggo
in order to use view
in HTTP we have to tell application where to look for views
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
func main() {
server := http.Server("127.0.0.1", 8080)
server.SetView("views", "html")
server.Route().Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.View("index", http.ViewData{
"name": "lucas11776",
})
})
fmt.Printf("Server running %s", server.Host())
server.Listen()
}
Then create a folder in current working directory called views
and create a file called views/index.html
and put below html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>View Reader</title>
</head>
<body>
<h1>Hello {{ name }} this is home page.</h1>
</body>
</html>
Static Assets
HTTP static allow allows us to specify a folder containing all webpage assets like CSS
, JavaScript
, Images
etc.
To get start lets create static
folder and in static
folder create a file called main.css
- static/main.css
.
body {
margin: 0 !important;
padding: 0 !important;
background-color: limegreen;
}
h1 {
font-size: 5em;
color: #fff;
text-align: center;
text-decoration: underline;
font-family: fantasy;
margin: 5px 0px !important;
}
Now let create view called home.html
in the views
- views/home.html
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home Page</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<h1>Hello World!!!</h1>
</body>
</html>
Lets add static
to our server
but specifying static
path.
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
func main() {
server := http.Server("127.0.0.1", 8080)
server.SetView("views", "html").SetStatic("static")
server.Route().Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.View("home", http.ViewData{})
})
fmt.Println("Server running ", server.Host())
server.Listen()
}
And then visit 127.0.0.1:8080 and see what we got.
Websocket
HTTP support websocket without third party packages
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
"github.com/lucas11776-golang/http/ws"
)
func main() {
server := http.Server("127.0.0.1", 8080)
server.Route().Ws("/", func(req *http.Request, ws *ws.Ws) {
ws.OnReady(func(ws *ws.Ws) {
ws.OnMessage(func(data []byte) {
fmt.Println("On Message:", string(data))
})
ws.OnPing(func(data []byte) {
fmt.Println("On Ping:", string(data))
})
ws.OnPong(func(data []byte) {
fmt.Println("On Pong:", string(data))
})
ws.OnClose(func(data []byte) {
fmt.Println("On Close:", string(data))
})
ws.OnError(func(data []byte) {
fmt.Println("On Error:", string(data))
})
})
})
fmt.Printf("Server running %s", server.Host())
server.Listen()
}
Lets example websocket callback which are:
OnReady
- This event is called when then websocket handshake is complete.OnMessage
- This event is called when the is when data send through websocket connection.OnPing
- This event is called when the isping
event through websocket connection.OnPong
- This event is called when the ispong
event through websocket connection.OnClose
- This event is called when websocket connection is closed.OnError
- This event is called the is error through websocket connection.
The above is all about receiving data/events now lets create a simple websocket that send random coordinates every two seconds.
package main
import (
"fmt"
"math/rand"
"time"
"github.com/lucas11776-golang/http"
)
type Coordinate struct {
Longitude float32 `json:"longitude"`
Latitude float32 `json:"latitude"`
Altitude int `json:"altitude"`
}
func main() {
server := http.Server("127.0.0.1", 8080)
server.Route().Ws("coordinate", func(req *http.Request, ws *http.Ws) {
ws.OnReady(func(ws *http.Ws) {
for {
if !ws.Alive {
break
}
time.Sleep(time.Second * 2)
ws.WriteJson(Coordinate{
Longitude: rand.Float32() * 360,
Latitude: rand.Float32() * 180,
Altitude: int(rand.Float32() * 100),
})
}
})
})
fmt.Println("Server running ", server.Host())
server.Listen()
}
Here is simple JavaScript
code to listen to coordinates from the server.
const ws = new WebSocket("ws://127.0.0.1:8080/coordinate");
ws.onopen = () => {
ws.onmessage = e => console.log(JSON.parse(e.data));
}
ws.onclose = e => console.log(e)
The are three type of writes which are:
Write
- This will write/send text payload to websocket connection.WriteBinary
- This will write/send binary payload to websocket connection.WriteJson
- This will convertstruct
/map
to json string and write/send to connection.
Middleware
What`s an application without middleware/guard to protected routes from unauthorized request or unwanted request below is simple route with middleware.
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
type Message struct {
Message string `json:"message"`
}
func Authorization(req *http.Request, res *http.Response, next http.Next) *http.Response {
if req.GetHeader("auth-key") != "test@123" {
return res.SetStatus(http.HTTP_RESPONSE_UNAUTHORIZED).Json(Message{
Message: "Unauthorized Access",
})
}
return next()
}
func main() {
server := http.Server("127.0.0.1", 8080)
server.Route().Middleware(Authorization).Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.Json(Message{
Message: "Hello World, You Authorized To See This Route...",
})
})
fmt.Println("Server running ", server.Host())
server.Listen()
}
If you visit
127.0.0.1:8080 with Postman or you favorite API testing tool without header Auth-Key
with value of test@123
you will get code status 401
with message Unauthorized Access
.
Session
HTTP support session to allow us to store user data
like user ID, user role etc below is a simple code of how session works we will example everything below the sample code.
package main
import (
"fmt"
"github.com/lucas11776-golang/http"
)
// Comment
func IsUser(req *http.Request, res *http.Response, next *http.Next) *http.Response {
if req.Session.Get("user_id") != "" {
return res.Redirect("/")
}
return next()
}
// Comment
func IsGuest(req *http.Request, res *http.Response, next *http.Next) *http.Response {
if req.Session.Get("user_id") != "" {
return res.Redirect("/")
}
return next()
}
func main() {
server := http.Server("127.0.0.1", 8080)
// Initialize application session
server.Session([]byte("session-key"))
server.Route().Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.Html("<h1>Home Page</h1>")
})
server.Route().Group("authentication", func(route *http.Router) {
route.Group("login", func() {
route.Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.Html("<h1>Add Post form to login</h1>")
})
route.Post("/", func(req *http.Request, res *http.Response) *http.Response {
res.Session.Set("user_id", "1") // or req.Session.Set("user_id", "1")
return res.Redirect("dashboard")
})
}).Middleware(IsGuest)
route.Post("logout", func(req *http.Request, res *http.Response) *http.Response {
res.Session.Remove("user_id")
return res.Redirect("authentication/login")
}).Middleware(IsUser)
})
server.Route().Middleware(IsUser).Group("dashboard", func(route *http.Router) {
route.Get("/", func(req *http.Request, res *http.Response) *http.Response {
return res.Html("<h1>Dashboard Page Can Be Viewed By Login Users</h1>")
})
})
fmt.Printf("Server running %s", server.Host())
server.Listen()
}
Issues
Having issues with HTTP framework contact me on:
- Email - [email protected]
- Linkedin - lucas11776