Basics
All internals of the framework are exposed. You can modify these internals, in fact it is intended for you to do so whenever you're in a state of urgency,
you're hitting a performance wall that needs to be solved immediately, a bug comes up and so on. Note
You are also welcome to contribute back if you can. Server
Create a new server with servers.New() , then followup with servers.Start() in order to start the server. package main
import (
"main/lib/core/servers"
"main/lib/core/ssr"
)
func main() {
server := servers.New() // Creates server.
server.Render = ssr.New(1) // Creates and assigns render function to server.
servers.Start(server) // Starts server.
} Note
ssr.New() creates a function that is capable executing JavaScript code on the server. This is what enables Server Side Rendering for your server, as the package name implies.
Caution
The first parameter of ssr.New() indicates how many runtimes should be created and executed
in parallel when rendering views.
Setting this value too high could lead to unnecessary large memory usage by your JavaScript runtimes.
For most use cases a limit of 1 runtime is more than enough.
Modify based on actual performance benchmarks.
Tip
If you don't plan to use SSR features then create your render function using csr.New() instead. package main
import (
"main/lib/core/servers"
"main/lib/core/csr"
)
func main() {
server := servers.New() // Creates server.
server.Render = csr.New() // Creates and assigns render function to server.
servers.Start(server) // Starts server.
} This will disable the server side JavaScript runtime, and because of that the minimum size of the final
binary will be reduced from 25MB to 10MB. Routes
Each server exposes a slice of Routes which you can freely modify. You can add a new route by appending to or overwriting server.Routes . package main
import (
"main/lib/core/servers"
"main/lib/routes/welcome"
)
func main() {
server := servers.New() // Creates server.
server.Routes = []routes.Route{ // Overwrites routes.
{Pattern: "GET /", Handler: welcome.View}, // Adds route.
}
_ = servers.Start(server) // Starts server.
} Where welcome.View is a function pointer. package welcome
import "main/lib/core/clients"
func View(client *clients.Client) {} Path Fields
Route patterns can define dynamic path fields using {} syntax. routes.Route{Pattern: "GET /{name}", Handler: welcome.View} Path fields can then be retrieved with receive.Path() . package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
)
func View(client *clients.Client) {
_ = receive.Path(client, "name") // Retrieves field "name".
} Messages
Use receive.Message() to retrieve messages sent by the client. package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
)
func View(client *clients.Client) {
_ = receive.Message(client) // Retrieves message.
} Use send.Message() to send a message to the client. package welcome
import (
"main/lib/core/clients"
"main/lib/core/send"
)
func View(client *clients.Client) {
send.Message(client, "Hello.") // Sends message.
} Use receive.Header() to retrieve header fields sent by the client. package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
)
func View(client *clients.Client) {
_ = receive.Header(client, "Accept") // Retrieves field "Accept".
} Use send.Header() to send header fields to the client. package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
"main/lib/core/send"
)
func View(client *clients.Client) {
accept := receive.Header(client, "Accept") // Retrieves field "Accept".
send.Header(client, "Content-Type", accept) // Sends it back.
} Status
Use send.Status() to send the status of the response to the client. package welcome
import (
"main/lib/core/clients"
"main/lib/core/send"
)
func View(client *clients.Client) {
send.Status(client, 404) // Sends status 404.
send.Message(client, "Not found.") // Sends message.
} Caution
Sending header fields or status after sending out content is not allowed. Read below. Order of Operations
Order of operations matters when sending data to the client. For example, sending the status code with send.Status() after you’ve already sent content with send.Message() is not allowed. package welcome
import (
"main/lib/core/clients"
"main/lib/core/send"
)
func View(client *clients.Client) {
send.Message(client, "Hello.") // Sends message (Succeeds).
send.Status(client, 404) // Sends status (Fails).
} send.Status(client, 404) will fail and the client will receive status 200 instead of 404. HTTP/1.1 200 OK
Date: Sun, 25 May 2025 02:00:37 GMT
Content-Length: 6
Content-Type: text/plain; charset=utf-8
Hello.
The failure is logged to the server’s error logger. Assuming you’re using the default error logger, you’ll see an error of sorts in your console listening for requests at http://127.0.0.1:8080
status is locked
status is locked , meaning the status code has already been sent to the client and
there’s nothing you can do about it. Queries
Use receive.Query() to retrieve query fields. package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
"main/lib/core/send"
)
func View(client *clients.Client) {
name := receive.Query(client, "name") // Retrieves field "name".
send.Message(client, "Hello " + name) // Sends message.
} Forms
Use receive.Form() to parse incoming content as multipart form or url encoded form when using POST and GET http verbs. routes.Route{Pattern: "POST /", Handler: welcome.View}
// or
routes.Route{Pattern: "GET /", Handler: welcome.View} package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
"main/lib/core/send"
)
type Form struct { // Defines a struct in which to
Name string `form:"name"` // store the form content.
}
func View(client *clients.Client) {
var form Form
receive.Form(client, &form) // Retrieves form.
send.Message(client, "Hello " + form.Name) // Sends message.
} Tip
You can also use a json tag, it will match the field correctly as if it were a form tag.
This is so that you can integrate your structs more easily with other libraries that only take into account json formats.
Tip
Form structs can define slices and files. type Form struct {
Name string `form:"name"`
Comments []string `form:"comments"` // Slice of strings.
File multipart.FileHeader `form:"file"` // File handler.
} You can open and read the file. src, _ := form.File.Open()
dst, _ := os.Create("my-file.txt")
io.Copy(src, dst) Remember to close your files. defer src.Close()
defer dst.Close()
Json
Use receive.Json() to parse incoming content as json when using POST and PUT http verbs and send.Json() to send json content. routes.Route{Pattern: "POST /", Handler: welcome.View}
// or
routes.Route{Pattern: "PUT /", Handler: welcome.View} package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
"main/lib/core/send"
)
type GreetingDetails struct { // Defines a struct in which to
Name string `json:"name"` // store the json content.
}
func View(client *clients.Client) {
var details GreetingDetails // Creates a zero value.
receive.Json(client, &details) // Unmarshals the content into details.
send.Json(client, details) // Sends content back as json.
} Cookies
Use receive.Cookie() to retrieve cookies and send.Cookie() to send
them. package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
"main/lib/core/send"
)
func View(client *clients.Client) {
nickname := receive.Cookie(client, "nickname") // Retrieves cookie.
send.Cookie(client, "nickname", nickname) // Sends it back.
} Session Id
Use receive.SessionId() to retrieve the client’s session id. package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
)
func View(client *clients.Client) {
_ = receive.SessionId(client) // Retrieves session id.
} Note
The session id is retrieved from the client’s session-id cookie. If the client doesn’t provide such cookie, receive.SessionId() creates a new session id and sends the cookie to the client.
Caution
Since receive.SessionId() might send a cookie to the client, it is important to remember
that order of operations matters.
Session
Use receive.Session() to retrieve the client’s session. Note
The session is retrieved using receive.SessionId() .
package welcome
import (
"main/lib/core/clients"
"main/lib/core/receive"
)
func View(client *clients.Client) {
var session *sessions.Session // Creates a zero value.
_ = receive.Session(client, &session) // Unmarshals the content into session.
} Redirect
Use send.Redirect() to redirect to a different location. package welcome
import (
"main/lib/core/clients"
"main/lib/core/send"
)
func View(client *clients.Client) {
send.Redirect(client, "/login", 307) // Redirects to /login.
} Navigate
Use send.Navigate() to redirect to a different location with status 302. package welcome
import (
"main/lib/core/clients"
"main/lib/core/send"
)
func View(client *clients.Client) {
send.Navigate(client, "/login") // Redirects to /login with status 302.
}