- create main directory
- create main.go file
- declare package main
- declare main function
- import fmt package
- make a call to fmt.Println and print "Hello world, my name is <your_name_here>"
- create datamodel.go file
- create AuthorDto struct with the following fields:
- UUID string
- FirstName string
- LastName string
- Birthday string
- Death string
- create BookDto struct with the following fields:
- UUID string
- Title string
- NoPages int
- ReleaseDate string
- Author AuthorDto
- create a slice of AuthorDto which will hold all authors in the system
- create a slice of BookDto which will hold all books in the system
- map AuthorDto.UUID field to uuid field in the resulting JSON
- map AuthorDto.FirstName field to firstName field in the resulting JSON
- map AuthorDto.LastName field to lastName field in the resulting JSON
- map AuthorDto.Birthday field to birthday field in the resulting JSON
- map AuthorDto.Death field to death field in the resulting JSON
- map BookDto.UUID field to uuid field in the resulting JSON
- map BookDto.Title field to title field in the resulting JSON
- map BookDto.NoPages field to noPages field in the resulting JSON
- map BookDto.ReleaseDate field to releaseDate field in the resulting JSON
- map BookDto.Author field to author field in the resulting JSON
- create model package
- move datamodel.go in model folder
- create importer package
- create authors.json file in importer folder
- add an array of authors with sample data in JSON format
- create books.json file in importer folder
- add an array of books with sample data in JSON format
- create dataImporter.go file in importer folder
- import encoding/json package
- import io/ioutil
- create a function named ImportAuthors that reads authors.json file and return a slice of authors
- create a function named ImportBooks that reads the books.json file and returns a slice of books
- print all authors to the STDOUT
- print all books to the STDOUT
- create web package
- create webserver.go
- import net/http
- read listening port from API_PORT environment variable, defaulting to 8000
- define a http.Handler function that will handle the incoming HTTP requests to the web server
- launch the web server on API_PORT port by calling ListenAndServe
- if the web server returns an error, exit the application
- change the path of the REST endpoint from /test to /books
- configure the handler to respond only to GET methods
- marshal the books array to JSON bytes
- convert the JSON bytes to string
- set the "Content-Type" response header to "application/json"
- when /books endpoint is hit, return all books previously loaded from the JSON file
- install github.com/gorilla/mux package using 'go get -u' command
- create util.go file in web package and implement a generic function that should write any array of data as JSON to the http.ResponseWriter
- create routes.go file
- define authorBaseUrl, authorByUuidUrl, booksBaseUrl, bookByUuidUrl constants with proper values
- define a Route struct with Method, Pattern, ExpectedCode and HandlerFunc fields
- define a Routes struct which should contain an array of Route structs
- declare a variable named routes of type Route and define all the routes mappings
- create author_handlers.go file in web package
- create book_handlers.go file in web package
- in each file, create HTTP handlers for:
- get all entities
- get entity by id
- delete entity by id
- add new entity
- update entity
- use mux.Vars(r)["..."] to extract path variables
- in webserver.StartServer function, create a Gorilla mux router, register the routes array with the router and then start the http server with the router as handler
- use go get to retrieve github.com/jinzhu/gorm package
- use go get to retrieve github.com/jinzhu/gorm/dialects/postgres
- create persistence package
- create config.go file in persistence package
- import for side effects github.com/jinzhu/gorm/dialects/postgres
- create an InitDB function that uses gorm.Open to open a connection to a PostgreSQL db
- gorm.Open should receive the following parameters: dialect, host, port, user, password, dbname, sslmode
- on the DBInstance set DB().SetMaxOpenConns, LogMode, SingularTable, AutoMigrate for Book and Author entities, add foreign constraint from Book to Author and add unique constraint on book title
- delete importer package
- remove importer references from main.go
- remove importer references from book_handlers.go
- remove importer references from author_handlers.go
- rename BookDto to Book and AuthroDto to Author
- create an Entity struct in datamodel.go file with UUID field
- add
gorm:"primary_key"
primary key annotation to the Entity.UUID field - embed Entity struct in Book struct
- add
gorm:"ForeignKey:AuthorUUID"
foreign key annotation to the Book.Author field - add
sql:"type:text REFERENCES author(uuid) ON DELETE CASCADE"
cascade delete annotation to the Book.AuthorUUID field - embed Entity struct in the Author struct
- create datastore.go file in persistence package
- create GormDataStore struct with a field named DBInstance of a type representing a pointer to a gorm.DB
- create DataStore interface in datastore.go with all books and authors operations
- create a Store variable of DataStore type
- in persistence/config.go file initialize the store variable before returning the DBInstance
- create books_datastore.go file in persistence package
- create authors_datastore.go file in persistence package
- implement DataStore interface in books_datastore.go and authors_datastore.go files by creating functions with a pointer receiver to a gorm.DB type
- in main.go init the persistence
- in web/book_handlers remove Books type and books variable
- in web/author_handlers remove Authors type and authors variable
- use methods on persistence.Store to work with Book and Author entities
#Part 3 - Add error handling and logging