Skip to content

Instantly share code, notes, and snippets.

@hoangsonww
Last active March 9, 2025 07:17
Show Gist options
  • Select an option

  • Save hoangsonww/26ecc8ee7e90f279d710d66acb5df5c0 to your computer and use it in GitHub Desktop.

Select an option

Save hoangsonww/26ecc8ee7e90f279d710d66acb5df5c0 to your computer and use it in GitHub Desktop.
A comprehensive Go backend for a Library Management System using the Beego framework, providing API endpoints for managing books, authors, borrowers, and book borrowing/returning.
package main
import (
"encoding/json"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"time"
)
// BookController handles operations related to books
type BookController struct {
beego.Controller
}
// Create handles adding a new book
func (b *BookController) Create() {
var book Book
json.Unmarshal(b.Ctx.Input.RequestBody, &book)
o := orm.NewOrm()
_, err := o.Insert(&book)
if err != nil {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Failed to create book"}
} else {
b.Ctx.Output.SetStatus(201)
b.Data["json"] = map[string]string{"message": "Book created successfully"}
}
b.ServeJSON()
}
// GetAll retrieves all books
func (b *BookController) GetAll() {
o := orm.NewOrm()
var books []Book
o.QueryTable(new(Book)).RelatedSel().All(&books)
b.Data["json"] = books
b.ServeJSON()
}
// GetOne retrieves a single book by ID
func (b *BookController) GetOne() {
id, _ := b.GetInt(":id")
o := orm.NewOrm()
book := Book{Id: id}
err := o.Read(&book)
if err == orm.ErrNoRows {
b.Ctx.Output.SetStatus(404)
b.Data["json"] = map[string]string{"error": "Book not found"}
} else {
b.Data["json"] = book
}
b.ServeJSON()
}
// Update modifies an existing book
func (b *BookController) Update() {
id, _ := b.GetInt(":id")
var book Book
json.Unmarshal(b.Ctx.Input.RequestBody, &book)
book.Id = id
o := orm.NewOrm()
_, err := o.Update(&book)
if err != nil {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Failed to update book"}
} else {
b.Ctx.Output.SetStatus(200)
b.Data["json"] = map[string]string{"message": "Book updated successfully"}
}
b.ServeJSON()
}
// Delete removes a book by ID
func (b *BookController) Delete() {
id, _ := b.GetInt(":id")
o := orm.NewOrm()
_, err := o.Delete(&Book{Id: id})
if err != nil {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Failed to delete book"}
} else {
b.Ctx.Output.SetStatus(200)
b.Data["json"] = map[string]string{"message": "Book deleted successfully"}
}
b.ServeJSON()
}
// AuthorController handles operations related to authors
type AuthorController struct {
beego.Controller
}
// Create handles adding a new author
func (a *AuthorController) Create() {
var author Author
json.Unmarshal(a.Ctx.Input.RequestBody, &author)
o := orm.NewOrm()
_, err := o.Insert(&author)
if err != nil {
a.Ctx.Output.SetStatus(400)
a.Data["json"] = map[string]string{"error": "Failed to create author"}
} else {
a.Ctx.Output.SetStatus(201)
a.Data["json"] = map[string]string{"message": "Author created successfully"}
}
a.ServeJSON()
}
// GetAll retrieves all authors
func (a *AuthorController) GetAll() {
o := orm.NewOrm()
var authors []Author
o.QueryTable(new(Author)).All(&authors)
a.Data["json"] = authors
a.ServeJSON()
}
// GetOne retrieves a single author by ID
func (a *AuthorController) GetOne() {
id, _ := a.GetInt(":id")
o := orm.NewOrm()
author := Author{Id: id}
err := o.Read(&author)
if err == orm.ErrNoRows {
a.Ctx.Output.SetStatus(404)
a.Data["json"] = map[string]string{"error": "Author not found"}
} else {
a.Data["json"] = author
}
a.ServeJSON()
}
// Update modifies an existing author
func (a *AuthorController) Update() {
id, _ := a.GetInt(":id")
var author Author
json.Unmarshal(a.Ctx.Input.RequestBody, &author)
author.Id = id
o := orm.NewOrm()
_, err := o.Update(&author)
if err != nil {
a.Ctx.Output.SetStatus(400)
a.Data["json"] = map[string]string{"error": "Failed to update author"}
} else {
a.Ctx.Output.SetStatus(200)
a.Data["json"] = map[string]string{"message": "Author updated successfully"}
}
a.ServeJSON()
}
// Delete removes an author by ID
func (a *AuthorController) Delete() {
id, _ := a.GetInt(":id")
o := orm.NewOrm()
_, err := o.Delete(&Author{Id: id})
if err != nil {
a.Ctx.Output.SetStatus(400)
a.Data["json"] = map[string]string{"error": "Failed to delete author"}
} else {
a.Ctx.Output.SetStatus(200)
a.Data["json"] = map[string]string{"message": "Author deleted successfully"}
}
a.ServeJSON()
}
// BorrowerController handles operations related to borrowers
type BorrowerController struct {
beego.Controller
}
// Create handles adding a new borrower
func (b *BorrowerController) Create() {
var borrower Borrower
json.Unmarshal(b.Ctx.Input.RequestBody, &borrower)
o := orm.NewOrm()
_, err := o.Insert(&borrower)
if err != nil {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Failed to create borrower"}
} else {
b.Ctx.Output.SetStatus(201)
b.Data["json"] = map[string]string{"message": "Borrower created successfully"}
}
b.ServeJSON()
}
// GetAll retrieves all borrowers
func (b *BorrowerController) GetAll() {
o := orm.NewOrm()
var borrowers []Borrower
o.QueryTable(new(Borrower)).All(&borrowers)
b.Data["json"] = borrowers
b.ServeJSON()
}
// GetOne retrieves a single borrower by ID
func (b *BorrowerController) GetOne() {
id, _ := b.GetInt(":id")
o := orm.NewOrm()
borrower := Borrower{Id: id}
err := o.Read(&borrower)
if err == orm.ErrNoRows {
b.Ctx.Output.SetStatus(404)
b.Data["json"] = map[string]string{"error": "Borrower not found"}
} else {
b.Data["json"] = borrower
}
b.ServeJSON()
}
// Update modifies an existing borrower
func (b *BorrowerController) Update() {
id, _ := b.GetInt(":id")
var borrower Borrower
json.Unmarshal(b.Ctx.Input.RequestBody, &borrower)
borrower.Id = id
o := orm.NewOrm()
_, err := o.Update(&borrower)
if err != nil {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Failed to update borrower"}
} else {
b.Ctx.Output.SetStatus(200)
b.Data["json"] = map[string]string{"message": "Borrower updated successfully"}
}
b.ServeJSON()
}
// Delete removes a borrower by ID
func (b *BorrowerController) Delete() {
id, _ := b.GetInt(":id")
o := orm.NewOrm()
_, err := o.Delete(&Borrower{Id: id})
if err != nil {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Failed to delete borrower"}
} else {
b.Ctx.Output.SetStatus(200)
b.Data["json"] = map[string]string{"message": "Borrower deleted successfully"}
}
b.ServeJSON()
}
// BorrowBook handles borrowing a book
func (b *BorrowerController) BorrowBook() {
var borrowRequest struct {
BookId int `json:"book_id"`
BorrowerId int `json:"borrower_id"`
}
json.Unmarshal(b.Ctx.Input.RequestBody, &borrowRequest)
o := orm.NewOrm()
book := Book{Id: borrowRequest.BookId}
borrower := Borrower{Id: borrowRequest.BorrowerId}
if err := o.Read(&book); err == orm.ErrNoRows || book.IsBorrowed {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Book not available"}
b.ServeJSON()
return
}
if err := o.Read(&borrower); err == orm.ErrNoRows {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Borrower not found"}
b.ServeJSON()
return
}
book.Borrower = &borrower
book.IsBorrowed = true
borrower.BorrowDate = time.Now()
o.Update(&book)
b.Ctx.Output.SetStatus(200)
b.Data["json"] = map[string]string{"message": "Book borrowed successfully"}
b.ServeJSON()
}
// ReturnBook handles returning a book
func (b *BorrowerController) ReturnBook() {
var returnRequest struct {
BookId int `json:"book_id"`
}
json.Unmarshal(b.Ctx.Input.RequestBody, &returnRequest)
o := orm.NewOrm()
book := Book{Id: returnRequest.BookId}
if err := o.Read(&book); err == orm.ErrNoRows || !book.IsBorrowed {
b.Ctx.Output.SetStatus(400)
b.Data["json"] = map[string]string{"error": "Book not borrowed"}
b.ServeJSON()
return
}
book.IsBorrowed = false
book.Borrower = nil
o.Update(&book)
b.Ctx.Output.SetStatus(200)
b.Data["json"] = map[string]string{"message": "Book returned successfully"}
b.ServeJSON()
}
package main
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
_ "github.com/mattn/go-sqlite3" // SQLite driver
)
func main() {
// Initialize the ORM and register the SQLite database
orm.RegisterDataBase("default", "sqlite3", "library.db")
orm.RegisterModel(new(Book), new(Author), new(Borrower))
orm.RunSyncdb("default", false, true) // Sync database schema
// Set up routes
beego.Router("/books", &BookController{}, "get:GetAll;post:Create")
beego.Router("/books/:id([0-9]+)", &BookController{}, "get:GetOne;put:Update;delete:Delete")
beego.Router("/authors", &AuthorController{}, "get:GetAll;post:Create")
beego.Router("/authors/:id([0-9]+)", &AuthorController{}, "get:GetOne;put:Update;delete:Delete")
beego.Router("/borrowers", &BorrowerController{}, "get:GetAll;post:Create")
beego.Router("/borrowers/:id([0-9]+)", &BorrowerController{}, "get:GetOne;put:Update;delete:Delete")
beego.Router("/borrow", &BorrowerController{}, "post:BorrowBook")
beego.Router("/return", &BorrowerController{}, "post:ReturnBook")
// Start the Beego application
beego.Run()
}
package main
import (
"time"
"github.com/astaxie/beego/orm"
)
type Book struct {
Id int
Title string
Author *Author `orm:"rel(fk)"`
IsBorrowed bool `orm:"default(false)"`
Borrower *Borrower `orm:"null;rel(fk)"`
}
type Author struct {
Id int
Name string
Books []*Book `orm:"reverse(many)"`
}
type Borrower struct {
Id int
Name string
BorrowedBooks []*Book `orm:"reverse(many)"`
BorrowDate time.Time `orm:"null"`
ReturnDate time.Time `orm:"null"`
}
func init() {
// Register the models
orm.RegisterModel(new(Book), new(Author), new(Borrower))
}
@hoangsonww
Copy link
Author

Library Management System API

This small project is a Library Management System built using the Beego framework in Go. It provides a backend API to manage books, authors, and borrowers, including functionalities to add, update, delete, and retrieve books and authors, as well as manage the borrowing and returning of books.

Features

  • Book Management: Add, update, delete, and retrieve books in the library.
  • Author Management: Add, update, delete, and retrieve authors.
  • Borrower Management: Add, update, delete, and retrieve borrowers.
  • Borrow and Return Books: Borrow and return books, ensuring a book can only be borrowed if it is available.
  • SQLite Database: Uses SQLite for persistent data storage.

Getting Started

Prerequisites

  • Go (version 1.15 or later)
  • Beego framework
  • SQLite

Installation

  1. Clone the repository:

    git clone https://github.com/yourusername/library-management-system.git
    cd library-management-system
  2. Install Beego and SQLite driver:

    go get github.com/astaxie/beego
    go get github.com/mattn/go-sqlite3
  3. Run the application:

    go run main.go models.go controllers.go
  4. API is available at:

    http://localhost:8080
    

API Endpoints

Books

  • Create a Book

    • Endpoint: POST /books
    • Description: Adds a new book to the library.
    • Request Body:
      {
        "title": "Book Title",
        "author": { "id": 1 } 
      }
    • Response:
      • 201 Created: Book created successfully.
      • 400 Bad Request: Failed to create book.
  • Get All Books

    • Endpoint: GET /books
    • Description: Retrieves all books in the library.
    • Response:
      • 200 OK: Returns a list of all books.
  • Get a Book by ID

    • Endpoint: GET /books/:id
    • Description: Retrieves a specific book by its ID.
    • Response:
      • 200 OK: Returns the book details.
      • 404 Not Found: Book not found.
  • Update a Book

    • Endpoint: PUT /books/:id
    • Description: Updates a book's information.
    • Request Body:
      {
        "title": "Updated Title",
        "author": { "id": 1 } 
      }
    • Response:
      • 200 OK: Book updated successfully.
      • 400 Bad Request: Failed to update book.
  • Delete a Book

    • Endpoint: DELETE /books/:id
    • Description: Deletes a book from the library.
    • Response:
      • 200 OK: Book deleted successfully.
      • 400 Bad Request: Failed to delete book.

Authors

  • Create an Author

    • Endpoint: POST /authors
    • Description: Adds a new author.
    • Request Body:
      {
        "name": "Author Name"
      }
    • Response:
      • 201 Created: Author created successfully.
      • 400 Bad Request: Failed to create author.
  • Get All Authors

    • Endpoint: GET /authors
    • Description: Retrieves all authors.
    • Response:
      • 200 OK: Returns a list of all authors.
  • Get an Author by ID

    • Endpoint: GET /authors/:id
    • Description: Retrieves a specific author by ID.
    • Response:
      • 200 OK: Returns the author details.
      • 404 Not Found: Author not found.
  • Update an Author

    • Endpoint: PUT /authors/:id
    • Description: Updates an author's information.
    • Request Body:
      {
        "name": "Updated Author Name"
      }
    • Response:
      • 200 OK: Author updated successfully.
      • 400 Bad Request: Failed to update author.
  • Delete an Author

    • Endpoint: DELETE /authors/:id
    • Description: Deletes an author.
    • Response:
      • 200 OK: Author deleted successfully.
      • 400 Bad Request: Failed to delete author.

Borrowers

  • Create a Borrower

    • Endpoint: POST /borrowers
    • Description: Adds a new borrower.
    • Request Body:
      {
        "name": "Borrower Name"
      }
    • Response:
      • 201 Created: Borrower created successfully.
      • 400 Bad Request: Failed to create borrower.
  • Get All Borrowers

    • Endpoint: GET /borrowers
    • Description: Retrieves all borrowers.
    • Response:
      • 200 OK: Returns a list of all borrowers.
  • Get a Borrower by ID

    • Endpoint: GET /borrowers/:id
    • Description: Retrieves a specific borrower by ID.
    • Response:
      • 200 OK: Returns the borrower details.
      • 404 Not Found: Borrower not found.
  • Update a Borrower

    • Endpoint: PUT /borrowers/:id
    • Description: Updates a borrower's information.
    • Request Body:
      {
        "name": "Updated Borrower Name"
      }
    • Response:
      • 200 OK: Borrower updated successfully.
      • 400 Bad Request: Failed to update borrower.
  • Delete a Borrower

    • Endpoint: DELETE /borrowers/:id
    • Description: Deletes a borrower.
    • Response:
      • 200 OK: Borrower deleted successfully.
      • 400 Bad Request: Failed to delete borrower.

Borrow and Return Books

  • Borrow a Book

    • Endpoint: POST /borrow
    • Description: Borrow a book from the library.
    • Request Body:
      {
        "book_id": 1,
        "borrower_id": 2
      }
    • Response:
      • 200 OK: Book borrowed successfully.
      • 400 Bad Request: Book not available or borrower not found.
  • Return a Book

    • Endpoint: POST /return
    • Description: Return a borrowed book.
    • Request Body:
      {
        "book_id": 1
      }
    • Response:
      • 200 OK: Book returned successfully.
      • 400 Bad Request: Book not borrowed or not found.

Testing

Use tools like Postman or curl to test the endpoints:

  • Example: Create a Book

    curl -X POST http://localhost:8080/books -H "Content-Type: application/json" -d '{"title": "The Great Gatsby", "author": {"id": 1}}'
  • Example: Borrow a Book

    curl -X POST http://localhost:8080/borrow -H "Content-Type: application/json" -d '{"book_id": 1, "borrower_id": 2}'

Contributing

Contributions are welcome! Please fork the repository and create a pull request with your changes.

License

This project is open-source and available under the MIT License.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment