Skip to content
Snippets Groups Projects
Commit ca059ca4 authored by Martin Schmollinger's avatar Martin Schmollinger
Browse files

Extended REST API: PUT, DELETE (campaign), POST (donation)

parent e05d0649
Branches
No related tags found
No related merge requests found
......@@ -36,6 +36,61 @@ func GetCampaigns(w http.ResponseWriter, _ *http.Request) {
sendJson(w, campaigns)
}
func UpdateCampaign(w http.ResponseWriter, r *http.Request) {
//extract id from url path
id, err := getId(r)
if err != nil {
//Bad Request
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
//Read Body
var campaign *model.Campaign
campaign, err = getCampaign(r)
if err != nil {
log.Printf("Error calling service UpdateCampaign: %v", err)
http.Error(w, err.Error(), http.StatusBadRequest)
}
//Call service function
campaign, err = service.UpdateCampaign(id, campaign)
if err != nil {
log.Errorf("Failure updating campaign with ID %v: %v", id, err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if campaign == nil {
http.Error(w, "404 campaign not found", http.StatusNotFound)
log.Errorf("Campaign with ID %v not found: %v", id, err)
return
}
//Send result OK
sendJson(w, campaign)
}
func DeleteCampaign(w http.ResponseWriter, r *http.Request) {
//extract id from url path
id, err := getId(r)
if err != nil {
//Bad Request
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
//Call service function DeleteCampaign
var campaign *model.Campaign
campaign, err = service.DeleteCampaign(id)
if err != nil {
log.Errorf("Failure deleting campaign with ID %v: %v", id, err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if campaign == nil {
log.Errorf("Campaign with ID %v not found: %v", id, err)
http.Error(w, "404 campaign not found", http.StatusNotFound)
return
}
sendJson(w, result{Success: "OK"})
}
func getCampaign(r *http.Request) (*model.Campaign, error) {
var campaign model.Campaign
err := json.NewDecoder(r.Body).Decode(&campaign)
......
......
package handler
import (
"encoding/json"
"net/http"
log "github.com/sirupsen/logrus"
"gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss25/src/myaktion/model"
"gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss25/src/myaktion/service"
)
func AddDonation(w http.ResponseWriter, r *http.Request) {
id, err := getId(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
donation, err := getDonation(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// TODO: if the campaign doesn't exist, return 404 - don't show FK error
err = service.AddDonation(id, donation)
if err != nil {
log.Errorf("Failure adding donation to campaign with ID %v: %v", id, err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sendJson(w, donation)
}
func getDonation(r *http.Request) (*model.Donation, error) {
var donation model.Donation
err := json.NewDecoder(r.Body).Decode(&donation)
if err != nil {
log.Errorf("Can't serialize request body to donation struct: %v", err)
return nil, err
}
return &donation, nil
}
......@@ -30,6 +30,9 @@ func main() {
router.HandleFunc("/health", handler.Health).Methods("GET")
router.HandleFunc("/campaigns", handler.CreateCampaign).Methods("POST")
router.HandleFunc("/campaigns", handler.GetCampaigns).Methods("GET")
router.HandleFunc("/campaigns/{id}", handler.UpdateCampaign).Methods("PUT")
router.HandleFunc("/campaigns/{id}", handler.DeleteCampaign).Methods("DELETE")
router.HandleFunc("/campaigns/{id}/donation", handler.AddDonation).Methods("POST")
if err := http.ListenAndServe(":8000", router); err != nil {
log.Fatal(err)
}
......
......
package service
import (
"errors"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
"gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss25/src/myaktion/db"
"gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss25/src/myaktion/model"
......@@ -17,6 +20,61 @@ func CreateCampaign(campaign *model.Campaign) error {
return nil
}
func UpdateCampaign(id uint, campaign *model.Campaign) (*model.Campaign, error) {
existingCampaign, err := GetCampaign(id)
if existingCampaign == nil || err != nil {
return existingCampaign, err
}
existingCampaign.Name = campaign.Name
existingCampaign.OrganizerName = campaign.OrganizerName
existingCampaign.TargetAmount = campaign.TargetAmount
existingCampaign.DonationMinimum = campaign.DonationMinimum
existingCampaign.Account = campaign.Account
result := db.DB.Save(existingCampaign)
if result.Error != nil {
return nil, result.Error
}
entry := log.WithField("ID", id)
entry.Info("Successfully updated campaign.")
entry.Tracef("Updated: %v", existingCampaign)
return existingCampaign, nil
}
func PatchCampaign(id uint, campaign *model.Campaign) (*model.Campaign, error) {
existingCampaign, err := GetCampaign(id)
if existingCampaign == nil || err != nil {
return existingCampaign, err
}
existingCampaign.Name = campaign.Name
existingCampaign.OrganizerName = campaign.OrganizerName
existingCampaign.TargetAmount = campaign.TargetAmount
existingCampaign.DonationMinimum = campaign.DonationMinimum
existingCampaign.Account = campaign.Account
result := db.DB.Save(existingCampaign)
if result.Error != nil {
return nil, result.Error
}
entry := log.WithField("ID", id)
entry.Info("Successfully updated campaign.")
entry.Tracef("Updated: %v", existingCampaign)
return existingCampaign, nil
}
func DeleteCampaign(id uint) (*model.Campaign, error) {
campaign, err := GetCampaign(id)
if campaign == nil || err != nil {
return campaign, err
}
result := db.DB.Delete(campaign)
if result.Error != nil {
return nil, result.Error
}
entry := log.WithField("ID", id)
entry.Info("Successfully deleted campaign.")
entry.Tracef("Deleted: %v", campaign)
return campaign, nil
}
func GetCampaigns() ([]model.Campaign, error) {
var campaigns []model.Campaign
result := db.DB.Preload("Donations").Find(&campaigns)
......@@ -26,3 +84,16 @@ func GetCampaigns() ([]model.Campaign, error) {
log.Tracef("Retrieved: %v", campaigns)
return campaigns, nil
}
func GetCampaign(id uint) (*model.Campaign, error) {
campaign := new(model.Campaign)
result := db.DB.Preload("Donations").First(campaign, id)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
if result.Error != nil {
return nil, result.Error
}
log.Tracef("Retrieved: %v", campaign)
return campaign, nil
}
package service
import (
log "github.com/sirupsen/logrus"
"gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss25/src/myaktion/db"
"gitlab.reutlingen-university.de/go-exercises/myaktion-go-ss25/src/myaktion/model"
)
func AddDonation(campaignId uint, donation *model.Donation) error {
donation.CampaignID = campaignId
result := db.DB.Create(donation)
if result.Error != nil {
return result.Error
}
entry := log.WithField("ID", campaignId)
entry.Info("Successfully added new donation to campaign in database.")
entry.Tracef("Stored: %v", donation)
return nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment