diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..7bc07ec
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Environment-dependent path to Maven home directory
+/mavenHomeManager.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/greenlight.iml b/.idea/greenlight.iml
new file mode 100644
index 0000000..25ed3f6
--- /dev/null
+++ b/.idea/greenlight.iml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..31e1ebc
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..475c31e
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e69de29
diff --git a/cmd/api/healthcheck.go b/cmd/api/healthcheck.go
new file mode 100644
index 0000000..c96a662
--- /dev/null
+++ b/cmd/api/healthcheck.go
@@ -0,0 +1,23 @@
+package main
+
+import (
+ "fmt"
+ "net/http"
+)
+
+/*
+Declare a handler which writes a plain-text response with information about the
+application status, operating environment and version
+*/
+/*
+Tips: The important thing to point out here is that healthcheckHandler is implemented as a method
+on our application struct. This is an effective and idiomatic way to make dependencies available
+to our handlers without resorting to global variables or closures - any dependency that the
+healthcheckHandler needs can simply be included as a field in the application struct when we
+initialize it in main()
+*/
+func (app *application) healthcheckHandler(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprintln(w, "status: available")
+ fmt.Fprintf(w, "environment: %s\n", app.config.env)
+ fmt.Fprintf(w, "version: %s\n", version)
+}
diff --git a/cmd/api/main.go b/cmd/api/main.go
new file mode 100644
index 0000000..ad26af5
--- /dev/null
+++ b/cmd/api/main.go
@@ -0,0 +1,89 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log/slog"
+ "net/http"
+ "os"
+ "time"
+)
+
+/*
+Declare a string containing the application version number.
+Later we'll generate this automatically at build time, but for now we'll just store the
+version number as a hard-coded global constant.
+*/
+const version = "1.0.0"
+
+/*
+Define a config struct to hold all the configuration settings for our application.
+For now, the only configuration settings will be the network port that we want the server to listen on,
+and the name of the current operating environment for the application (development, staging, production, etc.)
+We'll read in the configuration settings from command-line flags when the application starts.
+*/
+type config struct {
+ port int
+ env string
+}
+
+/*
+Define an application struct to hold the dependencies for our HTTP handlers, helpers,
+and middleware.
+*/
+type application struct {
+ config config
+ logger *slog.Logger
+}
+
+func main() {
+ // Declare an instance of the config struct.
+ var cfg config
+
+ /*
+ Read the value of the port and env command-line flags into the config struct.
+ We default to using the port number 4000 and the environment "development" if no corresponding flags are provided.
+ */
+ flag.IntVar(&cfg.port, "port", 4000, "API server port")
+ flag.StringVar(&cfg.env, "env", "development", "Environment (development|staging|production")
+ flag.Parse()
+
+ // Initialize a new structured logger which writes log entries to standard out stream.
+ logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
+
+ // Declare an instance of the application struct, containing the config struct and the logger.
+ app := &application{
+ config: cfg,
+ logger: logger,
+ }
+
+ /*
+ Declare a new servemux and add a /v1/healthcheck route which dispatches requests
+ to the healthcheckHandler method.
+ */
+ mux := http.NewServeMux()
+ mux.HandleFunc("/v1/healthcheck", app.healthcheckHandler)
+
+ /*
+ Declare a HTTP server which listens on the port provided in the config struct,
+ uses the servemux we created above as the handler, has some sensible timeout
+ settings and writes any log messages to the structured logger at Error level.
+ */
+ srv := &http.Server{
+ Addr: fmt.Sprintf(":%d", cfg.port),
+ Handler: mux,
+ IdleTimeout: time.Minute,
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError),
+ }
+
+ // Start the HTTP server.
+ logger.Info("starting server", "addr", srv.Addr, "env", cfg.env)
+
+ err := srv.ListenAndServe()
+ if err != nil {
+ logger.Error(err.Error())
+ os.Exit(1)
+ }
+}