diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5bc4d3f91d8e8632faf7a42cf0f8c5d0f2ed043a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,54 @@
+# To-Do API
+
+This is a backend for managing a simple task management application.
+The backend consists of three different parts:
+
+- Go application
+- SQLite (default)
+- PostgreSQL (optional)
+- NGINX (optional)
+
+An overview of the system can be seen here (dotted boxes indicates optional parts):
+
+![](architecture.png)
+
+## Go application
+
+In order to run the application, you need one dependency: "github.com/lib/pq","github.com/mattn/go-sqlite3".
+This can be retrieved by running `go get`.
+
+If you are using SQLite you may want to change the database file. 
+Update the following line in todo.go:
+sql.Open("sqlite3", "./foo.db")
+
+If you are using PostgreSQL you may want to update the database information to match your system.
+Update the following constants in todo.go:
+
+- databaseUser
+- databaseHost
+- databaseName
+
+## SQLite database 
+
+If SQLite is used to store all the list and todo information.
+In order to setup the database schema, run `sqlite3  foo.db < schema.sql`.
+
+## PostgreSQL database
+
+If PostgreSQL is used to store all the list and todo information.
+In order to setup the database schema, run `psql -f schema.sql db_name`.
+
+## NGINX (Optional)
+
+There is a configuration ready for using NGINX as a reverse proxy (in `nginx.conf`).
+However, the url to the application may need to be updated.
+
+## Run
+
+To build to application, simply use `go build` in the project directory.
+You can also use `go run todo.go` to run the server directly.
+
+## Test
+
+Test the system to make sure everything works.
+This is done by running `go test` in the application folder.
diff --git a/architecture.png b/architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..c77c5f8b3bb08e16b1174479156483cb34bfaa5c
Binary files /dev/null and b/architecture.png differ
diff --git a/nginx.conf b/nginx.conf
new file mode 100644
index 0000000000000000000000000000000000000000..40a47a21a6b6e8abb14acfb36b4d1b82773418a0
--- /dev/null
+++ b/nginx.conf
@@ -0,0 +1,27 @@
+user nginx;
+
+error_log  /var/log/nginx/error.log warn;
+pid        /var/run/nginx.pid;
+
+events{}
+
+http {
+    include       /etc/nginx/mime.types;
+    default_type  application/octet-stream;
+    keepalive_timeout  65;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                      '$status $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+    access_log  /var/log/nginx/access.log  main;
+
+    server {
+        listen 80;
+        proxy_pass_header Server;
+
+        location / {
+            # TODO: Update the url
+            proxy_pass http://app:8080;
+        }
+    }
+}
diff --git a/schema.sql b/schema.sql
new file mode 100644
index 0000000000000000000000000000000000000000..aaab4e1b0b79f5dee813526b334f1a25b1aa107c
--- /dev/null
+++ b/schema.sql
@@ -0,0 +1,15 @@
+-- A table that stores all the lists in the system.
+drop table if exists list;
+create table list(
+    id  integer primary key autoincrement,
+    name text not null
+);
+
+-- A table that stores all the tasks in the system.
+drop table if exists task;
+create table task(
+    id integer primary key autoincrement,
+    name text not null,
+    done boolean default false,
+    list int references list(id)
+);
diff --git a/todo.go b/todo.go
new file mode 100644
index 0000000000000000000000000000000000000000..501f3ffba455a53dd8140e5038401bf78bc66fcd
--- /dev/null
+++ b/todo.go
@@ -0,0 +1,214 @@
+package main
+
+import (
+	"database/sql"
+	"encoding/json"
+	"fmt"
+	_ "github.com/lib/pq"
+	_ "github.com/mattn/go-sqlite3"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"strconv"
+	"strings"
+)
+
+const (
+	databaseUser = "postgres"
+	databaseHost = "db"
+	databaseName = "postgres"
+)
+
+type Task struct {
+	Id     int
+	Name   string
+	Done   bool
+	ListId int
+}
+
+type CreateTaskRequest struct {
+	Name   string `json:"name"`
+	ListId int    `json:"list_id"`
+}
+
+type List struct {
+	Id   int
+	Name string
+}
+
+type ListCreateRequest struct {
+	Name string
+}
+
+type ListCreateResponse struct {
+	Id int
+}
+
+func CheckFatal(err error, w http.ResponseWriter) {
+	if err != nil {
+		w.WriteHeader(http.StatusInternalServerError)
+	}
+}
+
+type Database struct {
+	Db *sql.DB
+}
+
+// getURLParameter takes out the first URL parameter from the path
+// path should be formated as /type/param.
+// It returns a parameter representing a string.
+func getURLParameter(path string) *string {
+	// TODO: Handle multiple parameters
+	param := strings.Split(path, "/")
+	if len(param) == 3 {
+		return &param[2]
+	} else {
+		return nil
+	}
+}
+
+// getLists retrieves all the lists from the database.
+// It returns a slice of List structs.
+func getLists(db *sql.DB, w http.ResponseWriter) []List {
+	rows, err := db.Query("select * from list")
+	CheckFatal(err, w)
+
+	// Retrieve all lists from the query
+	res := make([]List, 0)
+	for rows.Next() {
+		list := List{}
+		err := rows.Scan(&list.Id, &list.Name)
+		CheckFatal(err, w)
+		res = append(res, list)
+	}
+
+	return res
+}
+
+// getTass retrieves all the tasks from the database.
+// It returns a slice of Task structs.
+func getTasks(db *sql.DB, listId int, w http.ResponseWriter) []Task {
+	// Query the database for all tasks that references the specified list
+	rows, err := db.Query("select * from task where list=$1", listId)
+	CheckFatal(err, w)
+
+	// Retrieve all tasks from the query
+	res := make([]Task, 0)
+	for rows.Next() {
+		var name string
+		var id, list int
+		var done bool
+		err := rows.Scan(&id, &name, &done, &list)
+		CheckFatal(err, w)
+		res = append(res, Task{Id: id, Name: name, Done: done, ListId: list})
+	}
+
+	return res
+}
+
+// insertList adds a list to the database with listName as its name.
+// It returns the Id of the list.
+func insertList(db *sql.DB, listName string, w http.ResponseWriter) int {
+	var listId int
+	//err := db.QueryRow("insert into list (name) values ($1) returning id", listName).Scan(&listId)
+	_, err := db.Exec("insert into list (name) values ($1) ", listName)
+	 db.QueryRow("select last_insert_rowid()").Scan(&listId) // SQLite specific 
+	CheckFatal(err, w)
+	return 0
+}
+
+// insertTask adds a task to the database.
+// taskName specifies the name of the task, and listId the list that it belongs to.
+func insertTask(db *sql.DB, taskName string, listId int, w http.ResponseWriter) {
+	_, err := db.Exec("insert into task (name, list) values ($1, $2)", taskName, listId)
+	// Handle non-existing list id
+	CheckFatal(err, w)
+}
+
+// listHandler manages requests with regards to the lists.
+// A GET request to /list will retrieve all the lists.
+// A GET request to /list/<id> will retrieve all the tasks of the list with id <id>.
+func (db *Database) listHandler(w http.ResponseWriter, r *http.Request) {
+	if r.Method == "GET" {
+		// Handle GET Request
+		param := getURLParameter(r.URL.Path)
+
+		// If no parameter exists, retrieve all lists
+		if param == nil || *param == "" {
+			// Retrieve lists
+			list := getLists(db.Db, w)
+			json.NewEncoder(w).Encode(&list)
+		} else {
+			// Get the list id from the parameter
+			listId, err := strconv.Atoi(*param)
+			CheckFatal(err, w)
+
+			// Retrieve tasks and send them back
+			tasks := getTasks(db.Db, listId, w)
+			json.NewEncoder(w).Encode(&tasks)
+		}
+	} else if r.Method == "POST" {
+		// Parse the request and create a new list
+		body, err := ioutil.ReadAll(r.Body)
+		CheckFatal(err, w)
+		listRequest := ListCreateRequest{}
+		err = json.Unmarshal(body, &listRequest)
+		CheckFatal(err, w)
+		listResponse := ListCreateResponse{}
+		listResponse.Id = insertList(db.Db, listRequest.Name, w)
+
+		json.NewEncoder(w).Encode(&listResponse)
+	}
+}
+
+// taskHandler manages requests with regards to the tasks.
+// A POST request to /task will create a new task with the name and list provided
+// in the Post Body. The Body should be in the format
+// {"name": "taskName", "list_id": 123}
+func (db *Database) taskHandler(w http.ResponseWriter, r *http.Request) {
+	if r.Method == "POST" {
+		body, err := ioutil.ReadAll(r.Body)
+		CheckFatal(err, w)
+		taskRequest := CreateTaskRequest{}
+		err = json.Unmarshal(body, &taskRequest)
+		CheckFatal(err, w)
+
+		insertTask(db.Db, taskRequest.Name, taskRequest.ListId, w)
+
+		fmt.Fprintf(w, "OK")
+	}
+}
+
+// ConnextDB connects to a postgres database.
+// it returns a database handle.
+func ConnectDb() *sql.DB {
+	// TODO: Refactor the database config
+	//for postgres database
+	//db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s@%s/%s?sslmode=disable", databaseUser, databaseHost, databaseName))
+	//for sqlite3 database
+	db, err := sql.Open("sqlite3", "./foo.db")
+	if err != nil {
+		log.Fatal(err)
+}
+
+
+	return db
+}
+
+// Handlers retrieves all handlers for the server.
+func Handlers() *http.ServeMux {
+	db := Database{Db: ConnectDb()}
+	mux := http.NewServeMux()
+	mux.Handle("/list", http.HandlerFunc(db.listHandler))
+	mux.Handle("/list/", http.HandlerFunc(db.listHandler))
+	mux.Handle("/task", http.HandlerFunc(db.taskHandler))
+	return mux
+}
+
+func main() {
+	// Listen on port 5050
+	err := http.ListenAndServe(":8080", Handlers())
+	if err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/todo_test.go b/todo_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..69939917474064ba5faff4872f900fa8e97ee83a
--- /dev/null
+++ b/todo_test.go
@@ -0,0 +1,149 @@
+package main
+
+import (
+    "io/ioutil"
+    "net/http"
+    "net/http/httptest"
+    "testing"
+    "strings"
+    "strconv"
+    "encoding/json"
+    "bytes"
+)
+
+// checkFail fails the tests if err is an error (not nil)
+func checkFail(t *testing.T, err error) {
+    if err != nil {
+        t.Fatal(err)
+    }
+}
+
+// setup recreates the database according to schema.sql.
+// This is so that all tests occurs from a clean slate
+func setup(t *testing.T) {
+    db := ConnectDb()
+    defer db.Close()
+
+    sqlData, err := ioutil.ReadFile("schema.sql")
+    checkFail(t, err)
+
+    sqlStmts := string(sqlData)
+    for _, stmt := range strings.Split(sqlStmts, ";") {
+        _, err := db.Exec(stmt)
+        checkFail(t, err)
+    }
+
+}
+
+// TestTask tests all functionality with regards to tasks
+func TestTask(test *testing.T) {
+    // Setup the database and create a test server
+    setup(test)
+    testServer := httptest.NewServer(Handlers())
+    defer testServer.Close()
+    // Create a new list for the different tasks
+    b, err := json.Marshal(ListCreateRequest{Name: "Work"})
+    checkFail(test, err)
+    res, err := http.Post(testServer.URL + "/list", "application/json", bytes.NewReader(b))
+    checkFail(test, err)
+    // Read the response and retrieve the id for the newly created list
+    listResp := ListCreateResponse{}
+    body, err := ioutil.ReadAll(res.Body)
+    defer res.Body.Close()
+    err = json.Unmarshal(body, &listResp)
+
+    // Get all the tasks from the new list
+    res, err = http.Get(testServer.URL + "/list/" + strconv.Itoa(listResp.Id))
+    checkFail(test, err)
+    if res.StatusCode != 200 {
+        test.Errorf("Expected 200 got %d", res.StatusCode)
+    }
+
+    body, err = ioutil.ReadAll(res.Body)
+    defer res.Body.Close()
+    var tasks []Task
+    err = json.Unmarshal(body, &tasks)
+    checkFail(test, err)
+
+    // There shouldn't be any tasks in the list yet
+    if len(tasks) != 0 {
+        test.Errorf("Expected len(tasks) == 0 got %d", len(tasks))
+    }
+
+    // Test the creation of a task in the list
+    b, err = json.Marshal(CreateTaskRequest{Name: "Work", ListId: listResp.Id})
+    checkFail(test, err)
+    res, err = http.Post(testServer.URL + "/task", "application/json", bytes.NewReader(b))
+    checkFail(test, err)
+    if res.StatusCode != 200 {
+        test.Errorf("Expected 200, got %d",res.StatusCode)
+    }
+
+    // Test the if the task got stored in the list
+    res, err = http.Get(testServer.URL + "/list/" + strconv.Itoa(listResp.Id))
+    checkFail(test, err)
+    if res.StatusCode != 200 {
+        test.Errorf("Expected 200 got %d", res.StatusCode)
+    }
+
+    // Check so that the list contains 1 task
+    body, err = ioutil.ReadAll(res.Body)
+    defer res.Body.Close()
+    err = json.Unmarshal(body, &tasks)
+    checkFail(test, err)
+    if len(tasks) != 1 {
+        test.Errorf("Expected len(tasks) == 1 got %d", len(tasks))
+    }
+}
+
+// TestList manages the testing of lists
+func TestList(test *testing.T) {
+    // Setup a clean database and a new test server
+    setup(test)
+    testServer := httptest.NewServer(Handlers())
+    defer testServer.Close()
+
+    // Retrieve the lists
+    res, err := http.Get(testServer.URL + "/list")
+    checkFail(test, err)
+    body, err := ioutil.ReadAll(res.Body)
+    res.Body.Close()
+    if res.StatusCode != 200 {
+        test.Errorf("Expected status code 200 got %d", res.StatusCode)
+    }
+
+    // Check that it didn't contain any lists
+    var lists []List
+    err = json.Unmarshal(body, &lists)
+    checkFail(test, err)
+
+    if len(lists) != 0 {
+        test.Errorf("Expected [] got %d", len(lists))
+    }
+
+    // Test creation of a list
+    b, err := json.Marshal(ListCreateRequest{Name: "Work"})
+    checkFail(test, err)
+    res, err = http.Post(testServer.URL + "/list", "application/json", bytes.NewReader(b))
+    checkFail(test, err)
+
+    if res.StatusCode != 200 {
+        test.Errorf("Expected status code 200 got %d", res.StatusCode)
+    }
+
+    // Make sure that the list is stored
+    res, err = http.Get(testServer.URL + "/list")
+    checkFail(test, err)
+    body, err = ioutil.ReadAll(res.Body)
+    res.Body.Close()
+
+    if res.StatusCode != 200 {
+        test.Errorf("Expected status code 200 got %d", res.StatusCode)
+    }
+
+    err = json.Unmarshal(body, &lists)
+    checkFail(test, err)
+    if len(lists) != 1 {
+        test.Errorf("Expected [] got len(%d)", len(lists))
+    }
+}