feat: add new notes example

This commit is contained in:
Daniel G. Taylor 2020-08-27 10:15:53 -07:00
parent c3c90161df
commit c4824ce846
No known key found for this signature in database
GPG key ID: 7BD6DC99C9A87E22

103
examples/notes/notes.go Normal file
View file

@ -0,0 +1,103 @@
package main
import (
"net/http"
"sync"
"time"
"github.com/danielgtaylor/huma"
"github.com/danielgtaylor/huma/cli"
"github.com/danielgtaylor/huma/middleware"
"github.com/danielgtaylor/huma/responses"
)
// NoteSummary is used to list notes. It does not include the (potentially)
// large note content.
type NoteSummary struct {
ID string `json:"id" doc:"Note ID"`
Created time.Time `json:"created" doc:"Created date/time as ISO8601"`
}
// NoteIDParam gets the note ID from the URI path.
type NoteIDParam struct {
NoteID string `path:"note-id" pattern:"^[a-zA-Z0-9._-]{1,32}$"`
}
// Note records some content text for later reference.
type Note struct {
Created time.Time `json:"created" readOnly:"true" doc:"Created date/time as ISO8601"`
Content string `json:"content" doc:"Note content"`
}
// We'll use an in-memory DB (a goroutine-safe map). Don't do this in
// production code!
var memoryDB = sync.Map{}
func main() {
// Create a new router and give our API a title and version.
app := cli.NewRouter("Notes API", "1.0.0")
app.Server("Development server", "http://localhost:8888")
notes := app.Resource("/v1/notes")
notes.Get("list-notes", "Returns a list of all notes",
responses.OK().Model([]*NoteSummary{}),
).Run(func(ctx huma.Context) {
// Create a list of summaries from all the notes.
summaries := make([]*NoteSummary, 0)
memoryDB.Range(func(k, v interface{}) bool {
summaries = append(summaries, &NoteSummary{
ID: k.(string),
Created: v.(Note).Created,
})
return true
})
ctx.WriteModel(http.StatusOK, summaries)
})
// Add an `id` path parameter to create a note resource.
note := notes.SubResource("note-id")
note.Put("put-note", "Create or update a note",
responses.NoContent(),
).Run(func(ctx huma.Context, input struct {
NoteIDParam
Body Note
}) {
// Set the created time to now and then save the note in the DB.
input.Body.Created = time.Now()
middleware.GetLogger(ctx).Info("Creating a new note")
memoryDB.Store(input.NoteID, input.Body)
})
note.Get("get-note", "Get a note by its ID",
responses.OK().Model(Note{}),
responses.NotFound(),
).Run(func(ctx huma.Context, input NoteIDParam) {
if n, ok := memoryDB.Load(input.NoteID); ok {
// Note with that ID exists!
ctx.WriteModel(http.StatusOK, n.(Note))
return
}
ctx.WriteError(http.StatusNotFound, "Note "+input.NoteID+" not found")
})
note.Delete("delete-note", "Delete a note by its ID",
responses.NoContent(),
responses.NotFound(),
).Run(func(ctx huma.Context, input NoteIDParam) {
if _, ok := memoryDB.Load(input.NoteID); ok {
// Note with that ID exists!
memoryDB.Delete(input.NoteID)
ctx.WriteHeader(http.StatusNoContent)
return
}
ctx.WriteError(http.StatusNotFound, "Note "+input.NoteID+" not found")
})
// Run the app!
app.Run()
}