Skip to content

Commit 12bda0c

Browse files
add exercises
1 parent e697857 commit 12bda0c

File tree

74 files changed

+3383
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+3383
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
// Create the Rectangle struct
8+
type Rectangle struct {
9+
Width float64
10+
Height float64
11+
}
12+
13+
// Define Area method
14+
func (r Rectangle) Area() float64 {
15+
return r.Width * r.Height
16+
}
17+
18+
// Define Perimeter method
19+
func (r Rectangle) Perimeter() float64 {
20+
return 2 * (r.Width + r.Height)
21+
}
22+
23+
func main() {
24+
// Create a new Rectangle
25+
rect := Rectangle{
26+
Width: 5.0,
27+
Height: 10.0,
28+
}
29+
30+
// Print area and perimeter
31+
fmt.Printf("Area: %.2f\n", rect.Area())
32+
fmt.Printf("Perimeter: %.2f\n", rect.Perimeter())
33+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Exercise: Structs
2+
3+
In this exercise, you'll practice creating a struct and adding methods to work with it.
4+
5+
First, navigate to **/L1. API Design Principles/1. Structs/starter/main.go**.
6+
7+
## Instructions:
8+
9+
1. Create a struct called `Rectangle` with two fields: ` Width` and `Height` (both of type `float64`).
10+
2. Define a method for the `Rectangle` struct called `Area()`, which calculates and returns the area of the rectangle.
11+
3. Define another method for the `Rectangle` struct called `Perimeter()`, which calculates and returns the perimeter of the rectangle.
12+
4. In the `main()` function, create a new `Rectangle` with a width of `5.0` and a height of `10.0`.
13+
5. Print out the area and perimeter of the rectangle using the methods you've defined.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
// TODO: Create the Rectangle struct
4+
5+
6+
// TODO: Define Area method
7+
8+
9+
// TODO: Define Perimeter method
10+
11+
func main() {
12+
// TODO: Create a new Rectangle
13+
14+
// TODO: Print area and perimeter
15+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"log"
6+
"net/http"
7+
)
8+
9+
func main() {
10+
// Register handlers for the routes
11+
http.HandleFunc("/", greet)
12+
http.HandleFunc("/user", userInfo)
13+
14+
// Serve on port 8080
15+
log.Fatal(http.ListenAndServe(":8080", nil))
16+
}
17+
18+
// greet responds with a simple greeting message
19+
func greet(w http.ResponseWriter, r *http.Request) {
20+
w.Write([]byte("Welcome to my server!"))
21+
}
22+
23+
// userInfo responds with a mock user data in JSON format
24+
func userInfo(w http.ResponseWriter, r *http.Request) {
25+
user := struct {
26+
Name string `json:"name"`
27+
Age int `json:"age"`
28+
Email string `json:"email"`
29+
}{
30+
Name: "Alice",
31+
Age: 25,
32+
33+
}
34+
35+
w.Header().Set("Content-Type", "application/json")
36+
json.NewEncoder(w).Encode(user)
37+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Exercise: Handlers
2+
3+
In this exercise, you'll use the `net/http` package to set up a simple web server with two routes: one that returns a greeting message and another that provides mock user data in JSON format.
4+
5+
By the end, your server will handle both plain text and JSON responses, giving you practical experience with HTTP handlers and JSON encoding in Go.
6+
7+
First, navigate to **/L1. API Design Principles/2. Handlers/starter/main.go**.
8+
9+
## Instructions:
10+
11+
1. Uncomment the commented code.
12+
2. Create two handler functions:
13+
14+
- `greet()`, which responds with a simple greeting message of your choice.
15+
- `userInfo()`, which responds with a JSON object representing a user with fields for name, age, and email.
16+
17+
3. Make sure to register your handlers using the appropriate `net/http` functions.
18+
4. Serve your application on port `8080`.
19+
5. Test your endpoints using a browser, cURL, or Postman to ensure the proper response formats (plain text for the greeting, and JSON for the user information).
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
)
7+
8+
func main() {
9+
// TODO: Register your handlers here
10+
11+
// TODO: Serve on port 8080
12+
log.Fatal(http.ListenAndServe(":8080", nil))
13+
}
14+
15+
// TODO: Define greet and userInfo handler functions here
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
"net/http"
8+
"strings"
9+
)
10+
11+
func main() {
12+
// Set up the route for the register endpoint and start the server on port 8080
13+
http.HandleFunc("/register", registerHandler)
14+
http.ListenAndServe(":8080", nil)
15+
}
16+
17+
func registerHandler(w http.ResponseWriter, r *http.Request) {
18+
// Ensure that only POST requests are allowed
19+
if r.Method != http.MethodPost {
20+
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
21+
return
22+
}
23+
24+
var user User
25+
// Decode the JSON body of the request into the User struct
26+
err := json.NewDecoder(r.Body).Decode(&user)
27+
if err != nil {
28+
// If the JSON is malformed or cannot be decoded, return a 400 error
29+
http.Error(w, "Invalid JSON data", http.StatusBadRequest)
30+
return
31+
}
32+
33+
// Validate the user input data
34+
err = validateUser(user)
35+
if err != nil {
36+
// If validation fails, return a 400 error with the specific error message
37+
http.Error(w, err.Error(), http.StatusBadRequest)
38+
return
39+
}
40+
41+
// If the input is valid, respond with a 200 status and success message
42+
w.WriteHeader(http.StatusOK)
43+
fmt.Fprintf(w, "Registration successful!")
44+
}
45+
46+
type User struct {
47+
Name string `json:"name"`
48+
Email string `json:"email"`
49+
Age int `json:"age"`
50+
}
51+
52+
func validateUser(user User) error {
53+
// Check if the name is empty
54+
if user.Name == "" {
55+
return errors.New("Name cannot be empty")
56+
}
57+
58+
// Check if the email contains an "@" symbol
59+
if !strings.Contains(user.Email, "@") {
60+
return errors.New("Invalid email address")
61+
}
62+
63+
// Ensure that the age is greater than 18
64+
if user.Age <= 18 {
65+
return errors.New("Age must be greater than 18")
66+
}
67+
68+
return nil
69+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Exercise: Data Validation
2+
3+
In this exercise, you'll practice implementing simple data validation on incoming requests in a Go web server. You will set up a basic API that accepts user registration details and responds with a success or error message depending on the validity of the provided data.
4+
5+
First, navigate to **/L1. API Design Principles/3. Data Validation/starter/main.go**.
6+
7+
# Instructions:
8+
9+
1. Create a new register handler function that accepts a POST request with a JSON payload containing `name`, `email`, and `age`.
10+
2. In your handler, implement the following validation rules:
11+
12+
- The `name` field cannot be empty.
13+
- The `email` field must contain an `@` symbol.
14+
- The `age` field must be a number greater than `21`.
15+
16+
3. If any of the data is invalid, return a `400 Bad Request` response with an error message.
17+
4. If all data is valid, return a `200 OK` response with a success message.
18+
5. Set up the server to run on port `8080`, and test your validation using tools like cURL or Postman.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
)
8+
9+
func main() {
10+
http.HandleFunc("/register", registerHandler)
11+
http.ListenAndServe(":8080", nil)
12+
}
13+
14+
func registerHandler(w http.ResponseWriter, r *http.Request) {
15+
// TODO: Implement handler logic
16+
}
17+
18+
type User struct {
19+
Name string `json:"name"`
20+
Email string `json:"email"`
21+
Age int `json:"age"`
22+
}
23+
24+
func validateUser(user User) error {
25+
// TODO: Implement validation logic
26+
return nil
27+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/http"
7+
8+
"gorm.io/driver/postgres"
9+
"gorm.io/gorm"
10+
)
11+
12+
type Task struct {
13+
ID uint `gorm:"primaryKey"`
14+
Title string
15+
Description string
16+
}
17+
18+
// Declare the database connection
19+
var db *gorm.DB
20+
21+
func main() {
22+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
23+
fmt.Fprintf(w, "Welcome to the Task Manager API!")
24+
})
25+
26+
// Set up a connection to the PostgreSQL database using GORM
27+
dsn := "host=localhost user=postgres password=yourpassword dbname=yourdb port=5432 sslmode=disable"
28+
var err error
29+
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
30+
if err != nil {
31+
log.Fatal("failed to connect to database:", err)
32+
}
33+
34+
// Auto-migrate the Task model to the database
35+
db.AutoMigrate(&Task{})
36+
37+
log.Println("Server running on port 8080")
38+
http.ListenAndServe(":8080", nil)
39+
}

0 commit comments

Comments
 (0)