Building a Booking App Codebase in Go: Easy Steps for Everyone
Overview
This Go application is a simple booking system for a conference. The application allows users to book tickets, validates user inputs, and sends booking confirmations via email. It utilizes concurrency for sending emails and includes basic input validation.
Package Imports
import (
"Booking-App/helper"
"fmt"
"sync"
"time"
)
fmt
: Used for formatted I/O operations.sync
: Provides basic synchronization primitives such as mutual exclusion locks.time
: Provides functionality for measuring and displaying time.Booking-App/helper
: A custom package for input validation.
Constants and Variables
Constants
const conferenceTickets int = 50
conferenceTickets
: The total number of tickets available for the conference.
Variables
var conferenceName = "Go Conference"
var remainingTickets uint = 50
var bookings = make([]UserData, 0)
var wg = sync.WaitGroup{}
conferenceName
: The name of the conference.remainingTickets
: The number of tickets still available.bookings
: A slice to store booking information.wg
: A WaitGroup to manage concurrent tasks.
Structs
UserData
type UserData struct {
firstName string
lastName string
email string
numberOfTickets uint
}
firstName
: The first name of the user.lastName
: The last name of the user.email
: The email address of the user.numberOfTickets
: The number of tickets booked by the user.
Main Function
main
func main() {
greetUsers()
firstName, lastName, email, userTickets := getUserInput()
isValidName, isValidEmail, isValidTicketNumber := helper.ValidateUserInput(firstName, lastName, email, userTickets, remainingTickets)
if isValidName && isValidEmail && isValidTicketNumber {
bookTicket(userTickets, firstName, lastName, email)
wg.Add(1)
go sendTicket(userTickets, firstName, lastName, email)
firstNames := getFirstNames()
fmt.Printf("The first names of bookings are: %v\n", firstNames)
if remainingTickets == 0 {
fmt.Println("Our conference is booked out. Come back next year")
}
} else {
if !isValidName {
fmt.Println("First name or last name you entered is too short")
}
if !isValidEmail {
fmt.Println("Email address you entered doesn't contain '@gmail.com' sign")
}
if !isValidTicketNumber {
fmt.Println("Number of tickets you entered is invalid")
}
}
wg.Wait()
}
greetUsers(): Greets the users and provides initial information about the conference.
getUserInput(): Prompts the user for their information and the number of tickets they want to book.
helper.ValidateUserInput(): Validates the user input for correctness.
bookTicket(): Books the tickets if the user input is valid.
sendTicket(): Sends the ticket confirmation email concurrently.
getFirstNames(): Retrieves the first names of all booked users.
wg.Wait(): Waits for all goroutines to finish.
Functions
greetUsers
func greetUsers() {
fmt.Printf("Welcome to %v booking application\n", conferenceName)
fmt.Printf("We have total of %v tickets and %v are still available.\n", conferenceTickets, remainingTickets)
fmt.Println("Get your tickets here to attend")
}
Greets users with the conference name and the number of available tickets.
getFirstNames
func getFirstNames() []string {
firstNames := []string{}
for _, booking := range bookings {
firstNames = append(firstNames, booking.firstName)
}
return firstNames
}
Returns a slice of first names from the bookings.
getUserInput
func getUserInput() (string, string, string, uint) {
var firstName string
var lastName string
var email string
var userTickets uint
fmt.Println("Enter your first name:")
fmt.Scan(&firstName)
fmt.Println("Enter your last name:")
fmt.Scan(&lastName)
fmt.Println("Enter your email:")
fmt.Scan(&email)
fmt.Println("Enter number of tickets:")
fmt.Scan(&userTickets)
return firstName, lastName, email, userTickets
}
bookTicket
func bookTicket(userTickets uint, firstName string, lastName string, email string) {
remainingTickets = remainingTickets - userTickets
var userData = UserData{
firstName: firstName,
lastName: lastName,
email: email,
numberOfTickets: userTickets,
}
bookings = append(bookings, userData)
fmt.Printf("List of bookings is %v\n", bookings)
fmt.Printf("Thank you %v %v for booking %d tickets. You will receive a confirmation email at %v\n", firstName, lastName, userTickets, email)
fmt.Printf("%v tickets remaining for %v\n", remainingTickets, conferenceName)
}
Updates the remaining tickets and adds the user data to the bookings slice.
Prints the booking confirmation and the updated number of remaining tickets.
sendTicket
func sendTicket(userTickets uint, firstName string, lastName string, email string) {
time.Sleep(50 * time.Second)
var ticket = fmt.Sprintf("%v tickets for %v %v", userTickets, firstName, lastName)
fmt.Println("####################")
fmt.Printf("Sending ticket:\n %v \nto email address %v\n", ticket, email)
fmt.Println("####################")
wg.Done()
}
Simulates sending an email by sleeping for 50 seconds.
Prints the ticket information and the recipient's email address.
Signals the WaitGroup that the goroutine is done.
Helper Package
The helper
package contains a function ValidateUserInput
that checks the validity of the user's input. This function ensures that names are of sufficient length, emails contain a specific domain, and the number of tickets requested is valid.
ValidateUserInput
package helper
import "strings"
func ValidateUserInput(firstName string, lastName string, email string, userTickets uint, remainingTickets uint) (bool, bool, bool) {
isValidName := len(firstName) >= 2 && len(lastName) >= 2
isValidEmail := strings.Contains(email, "@gmail.com")
isValidTicketNumber := userTickets > 0 && userTickets <= remainingTickets
return isValidName, isValidEmail, isValidTicketNumber
}
isValidName: Checks if the first and last names are at least 2 characters long.
isValidEmail: Checks if the email contains the '@gmail.com' domain.
isValidTicketNumber: Checks if the number of tickets requested is greater than 0 and does not exceed the remaining tickets.
Returns boolean values indicating whether each input is valid.
Summary
This Go application demonstrates a simple ticket booking system with user input validation and concurrency. It provides a clear example of using goroutines and WaitGroups for handling concurrent tasks, such as sending emails, and ensures that user inputs are validated before processing the booking. The application is modular, with a helper package for validation, making it easy to maintain and extend.
Subscribe to my newsletter
Read articles from Arijit Das directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by