Last active
September 7, 2023 19:45
-
-
Save DeedleFake/05eb4adad4f23a295a8038a2101c0445 to your computer and use it in GitHub Desktop.
An example of a very, very basic structure for a simple REST API in Go.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"database/sql" | |
"fmt" | |
"log/slog" | |
"net" | |
"net/http" | |
"os" | |
"os/signal" | |
) | |
type Server struct { | |
Addr string | |
db *sql.DB | |
} | |
func (s *Server) Run(ctx context.Context) error { | |
err := s.openDB(ctx) | |
if err != nil { | |
return fmt.Errorf("open database: %w", err) | |
} | |
defer s.db.Close() | |
server := http.Server{ | |
Addr: ":8080", | |
Handler: s.createRouter(), | |
BaseContext: func(net.Listener) context.Context { return ctx }, | |
} | |
// TODO: Setup graceful shutdown handling and whatnot. | |
err = server.ListenAndServe() | |
if err != nil { | |
return fmt.Errorf("listen and server: %w", err) | |
} | |
return nil | |
} | |
func (s *Server) openDB(ctx context.Context) error { | |
panic("Not implemented.") | |
} | |
func main() { | |
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) | |
defer cancel() | |
server := Server{ | |
Addr: ":8080", // TODO: Get this from somewhere. | |
} | |
err := server.Run(ctx) | |
if err != nil { | |
slog.Error("fatal error", "err", err) | |
os.Exit(1) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module http-structure-example | |
go 1.21.0 | |
require github.com/julienschmidt/httprouter v1.3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= | |
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log/slog" | |
"net/http" | |
) | |
// This could all probably be put into a package just for middleware or something. | |
func Log(h http.Handler, logger *slog.Logger) http.Handler { | |
if logger == nil { | |
logger = slog.Default() | |
} | |
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { | |
logger.Info("handle request", "method", req.Method, "url", req.URL.RequestURI()) | |
h.ServeHTTP(rw, req) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"net/http" | |
"github.com/julienschmidt/httprouter" | |
) | |
func (s *Server) createRouter() http.Handler { | |
router := httprouter.New() | |
router.Handler(http.MethodGet, "/user", Log(GetUser{DB: s.db}, nil)) | |
router.Handler(http.MethodPost, "/user", Log(CreateUser{DB: s.db}, nil)) | |
return router | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"database/sql" | |
"net/http" | |
) | |
// These can be moved into other packages in the module and whatnot if | |
// necessary as the number of endpoints increases. | |
type GetUser struct { | |
DB *sql.DB | |
} | |
func (h GetUser) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | |
panic("Not implemented.") | |
} | |
type CreateUser struct { | |
DB *sql.DB | |
} | |
func (h CreateUser) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | |
panic("Not implemented.") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment