127 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package api
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
	"sync"
 | 
						|
)
 | 
						|
 | 
						|
type PetStore struct {
 | 
						|
	Pets   map[int64]Pet
 | 
						|
	NextId int64
 | 
						|
	Lock   sync.Mutex
 | 
						|
}
 | 
						|
 | 
						|
// Make sure we conform to ServerInterface
 | 
						|
 | 
						|
var _ ServerInterface = (*PetStore)(nil)
 | 
						|
 | 
						|
func NewPetStore() *PetStore {
 | 
						|
	return &PetStore{
 | 
						|
		Pets:   make(map[int64]Pet),
 | 
						|
		NextId: 1000,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// sendPetStoreError wraps sending of an error in the Error format, and
 | 
						|
// handling the failure to marshal that.
 | 
						|
func sendPetStoreError(w http.ResponseWriter, code int, message string) {
 | 
						|
	petErr := Error{
 | 
						|
		Code:    int32(code),
 | 
						|
		Message: message,
 | 
						|
	}
 | 
						|
	w.WriteHeader(code)
 | 
						|
	_ = json.NewEncoder(w).Encode(petErr)
 | 
						|
}
 | 
						|
 | 
						|
// FindPets implements all the handlers in the ServerInterface
 | 
						|
func (p *PetStore) FindPets(w http.ResponseWriter, r *http.Request, params FindPetsParams) {
 | 
						|
	p.Lock.Lock()
 | 
						|
	defer p.Lock.Unlock()
 | 
						|
 | 
						|
	var result []Pet
 | 
						|
 | 
						|
	for _, pet := range p.Pets {
 | 
						|
		if params.Tags != nil {
 | 
						|
			// If we have tags,  filter pets by tag
 | 
						|
			for _, t := range *params.Tags {
 | 
						|
				if pet.Tag != nil && (*pet.Tag == t) {
 | 
						|
					result = append(result, pet)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			// Add all pets if we're not filtering
 | 
						|
			result = append(result, pet)
 | 
						|
		}
 | 
						|
 | 
						|
		if params.Limit != nil {
 | 
						|
			l := int(*params.Limit)
 | 
						|
			if len(result) >= l {
 | 
						|
				// We're at the limit
 | 
						|
				break
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	w.WriteHeader(http.StatusOK)
 | 
						|
	_ = json.NewEncoder(w).Encode(result)
 | 
						|
}
 | 
						|
 | 
						|
func (p *PetStore) AddPet(w http.ResponseWriter, r *http.Request) {
 | 
						|
	// We expect a NewPet object in the request body.
 | 
						|
	var newPet NewPet
 | 
						|
	if err := json.NewDecoder(r.Body).Decode(&newPet); err != nil {
 | 
						|
		sendPetStoreError(w, http.StatusBadRequest, "Invalid format for NewPet")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// We now have a pet, let's add it to our "database".
 | 
						|
 | 
						|
	// We're always asynchronous, so lock unsafe operations below
 | 
						|
	p.Lock.Lock()
 | 
						|
	defer p.Lock.Unlock()
 | 
						|
 | 
						|
	// We handle pets, not NewPets, which have an additional ID field
 | 
						|
	var pet Pet
 | 
						|
	pet.Name = newPet.Name
 | 
						|
	pet.Tag = newPet.Tag
 | 
						|
	pet.Id = p.NextId
 | 
						|
	p.NextId++
 | 
						|
 | 
						|
	// Insert into map
 | 
						|
	p.Pets[pet.Id] = pet
 | 
						|
 | 
						|
	// Now, we have to return the NewPet
 | 
						|
	w.WriteHeader(http.StatusCreated)
 | 
						|
	_ = json.NewEncoder(w).Encode(pet)
 | 
						|
}
 | 
						|
 | 
						|
func (p *PetStore) FindPetByID(w http.ResponseWriter, r *http.Request, id int64) {
 | 
						|
	p.Lock.Lock()
 | 
						|
	defer p.Lock.Unlock()
 | 
						|
 | 
						|
	pet, found := p.Pets[id]
 | 
						|
	if !found {
 | 
						|
		sendPetStoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	w.WriteHeader(http.StatusOK)
 | 
						|
	_ = json.NewEncoder(w).Encode(pet)
 | 
						|
}
 | 
						|
 | 
						|
func (p *PetStore) DeletePet(w http.ResponseWriter, r *http.Request, id int64) {
 | 
						|
	p.Lock.Lock()
 | 
						|
	defer p.Lock.Unlock()
 | 
						|
 | 
						|
	_, found := p.Pets[id]
 | 
						|
	if !found {
 | 
						|
		sendPetStoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
 | 
						|
		return
 | 
						|
	}
 | 
						|
	delete(p.Pets, id)
 | 
						|
 | 
						|
	w.WriteHeader(http.StatusNoContent)
 | 
						|
}
 |