aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaster4385 <blaster4385@tablaster.dev>2024-02-20 00:56:42 +0530
committerBlaster4385 <blaster4385@tablaster.dev>2024-02-21 23:55:16 +0530
commit3d8c332ad6deb0ea570393ca535c75dc524315bb (patch)
tree6fafd8c4090f7a28f096fe8253362ae30211dc15
parent4536ac2f90994fea7ef2d4046ff9e18dbf26205c (diff)
refactor: rewrite server and bundle entire application in a single binary
-rw-r--r--client/vite.config.js3
-rw-r--r--server/.gitignore3
-rw-r--r--server/go.mod20
-rw-r--r--server/go.sum33
-rw-r--r--server/main.go122
5 files changed, 100 insertions, 81 deletions
diff --git a/client/vite.config.js b/client/vite.config.js
index 1f72faa..707b9b9 100644
--- a/client/vite.config.js
+++ b/client/vite.config.js
@@ -32,4 +32,7 @@ export default defineConfig({
],
}),
],
+ build: {
+ outDir: '../server/dist'
+ }
});
diff --git a/server/.gitignore b/server/.gitignore
index c2cb318..035a135 100644
--- a/server/.gitignore
+++ b/server/.gitignore
@@ -23,3 +23,6 @@ minibin
# Go workspace file
go.work
+
+# Vite output directory
+dist/
diff --git a/server/go.mod b/server/go.mod
index c15dae4..f7cb82a 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -3,8 +3,20 @@ module minibin
go 1.22.0
require (
- github.com/google/uuid v1.6.0 // indirect
- github.com/gorilla/mux v1.8.1 // indirect
- github.com/mattn/go-sqlite3 v1.14.22 // indirect
- github.com/rs/cors v1.10.1 // indirect
+ github.com/labstack/echo/v4 v4.11.4
+ github.com/mattn/go-sqlite3 v1.14.22
+)
+
+require (
+ github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
+ github.com/labstack/gommon v0.4.2 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
+ github.com/valyala/fasttemplate v1.2.2 // indirect
+ golang.org/x/crypto v0.17.0 // indirect
+ golang.org/x/net v0.19.0 // indirect
+ golang.org/x/sys v0.15.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
+ golang.org/x/time v0.5.0 // indirect
)
diff --git a/server/go.sum b/server/go.sum
index a0572d7..79cf427 100644
--- a/server/go.sum
+++ b/server/go.sum
@@ -1,8 +1,29 @@
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
-github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
+github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
+github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
+github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
+github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
+github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
+github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
-github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
-github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
+github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
+golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
+golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
diff --git a/server/main.go b/server/main.go
index 4618e5b..4737f17 100644
--- a/server/main.go
+++ b/server/main.go
@@ -1,24 +1,22 @@
package main
import (
- "database/sql"
- "encoding/json"
+ "embed"
"flag"
- "fmt"
- "io/ioutil"
+ "github.com/labstack/echo/v4"
+ "github.com/labstack/echo/v4/middleware"
+ "database/sql"
"log"
"math/rand"
"net/http"
- "strings"
"time"
_ "github.com/mattn/go-sqlite3"
- "github.com/rs/cors"
)
var db *sql.DB
-var port int
var dbFilePath string
+var port string
type Bin struct {
Content string `json:"content"`
@@ -30,23 +28,33 @@ const (
shortIDLength = 8
)
-func main() {
- flag.IntVar(&port, "port", 8080, "Port number for the server (default is 8080)")
- flag.StringVar(&dbFilePath, "db", "./minibin.db", "Database file path")
- flag.Parse()
+var (
+ //go:embed all:dist
+ dist embed.FS
+)
- setupServer()
+func RegisterHandlers(e *echo.Echo) {
+ e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
+ Skipper: nil,
+ Root: "dist",
+ Index: "index.html",
+ HTML5: true,
+ Filesystem: http.FS(dist),
+ }))
+ e.Use(middleware.CORS())
+ e.POST("/bin", postBin)
+ e.GET("/bin/:id", getBin)
}
-func setupServer() {
- mux := http.NewServeMux()
- mux.HandleFunc("/bin", postBin)
- mux.HandleFunc("/bin/", getBin)
- handler := cors.Default().Handler(mux)
- serverAddr := fmt.Sprintf(":%d", port)
- log.Printf("Server listening on port %d...\n", port)
+func main() {
+ flag.StringVar(&port, "port", "8080", "HTTP server port")
+ flag.StringVar(&dbFilePath, "db", "minibin.db", "Path to SQLite database file")
+ flag.Parse()
+
initDatabase()
- log.Fatal(http.ListenAndServe(serverAddr, handler))
+ e := echo.New()
+ RegisterHandlers(e)
+ e.Logger.Fatal(e.Start(":" + port))
}
func initDatabase() {
@@ -62,68 +70,40 @@ func initDatabase() {
}
}
-func postBin(w http.ResponseWriter, r *http.Request) {
- handleRequestMethod(w, r, "POST", func() {
- body, err := ioutil.ReadAll(r.Body)
- if handleError(w, err, http.StatusInternalServerError) {
- return
- }
- var bin Bin
- err = json.Unmarshal(body, &bin)
- if handleError(w, err, http.StatusBadRequest) {
- return
- }
- id := generateShortID()
- handleError(w, saveBin(id, bin), http.StatusInternalServerError)
- respondWithJSON(w, http.StatusOK, map[string]string{"id": id, "content": bin.Content, "language": bin.Language})
- })
-}
-
-func getBin(w http.ResponseWriter, r *http.Request) {
- handleRequestMethod(w, r, "GET", func() {
- id := strings.TrimPrefix(r.URL.Path, "/bin/")
- bin, err := getBinById(id)
- handleError(w, err, http.StatusInternalServerError)
- respondWithJSON(w, http.StatusOK, bin)
- })
-}
-
-func handleRequestMethod(w http.ResponseWriter, r *http.Request, expectedMethod string, handler func()) {
- if r.Method != expectedMethod {
- http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
- return
+func postBin(echoContext echo.Context) error {
+ bin := Bin{}
+ err := echoContext.Bind(&bin)
+ if err != nil {
+ return err
}
- handler()
-}
-
-func handleError(w http.ResponseWriter, err error, statusCode int) bool {
+ id := generateShortID()
+ err = saveBin(id, bin)
if err != nil {
- http.Error(w, err.Error(), statusCode)
- return true
+ return err
}
- return false
+ return echoContext.JSON(http.StatusCreated, echo.Map{
+ "id": id,
+ })
}
-func respondWithJSON(w http.ResponseWriter, statusCode int, data interface{}) {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(statusCode)
- json.NewEncoder(w).Encode(data)
+func getBin(echoContext echo.Context) error {
+ id := echoContext.Param("id")
+ bin, err := getBinById(id)
+ if err != nil {
+ return err
+ }
+ return echoContext.JSON(http.StatusOK, bin)
}
func createTable() error {
- _, err := db.Exec(`
- CREATE TABLE IF NOT EXISTS bins (
- id TEXT PRIMARY KEY,
- content TEXT,
- language TEXT
- )
-`)
+ _, err := db.Exec("CREATE TABLE IF NOT EXISTS bins (id TEXT PRIMARY KEY, content TEXT, language TEXT)")
return err
}
func getBinById(id string) (Bin, error) {
- var bin Bin
- err := db.QueryRow("SELECT content, language FROM bins WHERE id = ?", id).Scan(&bin.Content, &bin.Language)
+ row := db.QueryRow("SELECT content, language FROM bins WHERE id = ?", id)
+ bin := Bin{}
+ err := row.Scan(&bin.Content, &bin.Language)
return bin, err
}
@@ -139,4 +119,4 @@ func generateShortID() string {
id[i] = shortIDCharset[rand.Intn(len(shortIDCharset))]
}
return string(id)
-}
+} \ No newline at end of file