Giter Site home page Giter Site logo

babyapi's Introduction

Baby API

GitHub go.mod Go version (subdirectory of monorepo) GitHub Workflow Status License Go Reference codecov

A Go CRUD API framework so simple a baby could use it.

babyapi is a super simple framework that automatically creates an HTTP API for create, read, update, and delete operations on a struct. Simply extend the babyapi.DefaultResource type to get started.

Implement custom request/response handling by implemented Renderer and Binder from go-chi/render. Use provided extension functions to add additional API functionality:

  • OnCreateOrUpdate: additional handling for create/update requests
  • Storage: set a different storage backend implementing the babyapi.Storage interface
  • AddCustomRoute: add more routes on the base API
  • Patch: add custom logic for handling PATCH requests
  • And many more! (see examples and docs)
  • Override any of the default handlers and use babyapi.Handler shortcut to easily render errors and responses

Getting Started

  1. Create a new Go module:
    mkdir babyapi-example
    cd babyapi-example
    go mod init babyapi-example
  2. Write main.go to create a TODO struct and initialize babyapi.API:
    package main
    
    import "github.com/calvinmclean/babyapi"
    
    type TODO struct {
        babyapi.DefaultResource
    
        Title       string
        Description string
        Completed   bool
    }
    
    func main() {
        api := babyapi.NewAPI[*TODO](
            "TODOs", "/todos",
            func() *TODO { return &TODO{} },
        )
        api.RunCLI()
    }
  3. Run!
    go mod tidy
    go run main.go serve
  4. Use the built-in CLI to interact with the API:
    # Create a new TODO
    go run main.go post TODOs '{"title": "use babyapi!"}'
    
    # Get all TODOs
    go run main.go list TODOs
    
    # Get TODO by ID (use ID from previous responses)
    go run main.go get TODOs cljvfslo4020kglbctog

Simple Example

Client

In addition to providing the HTTP API backend, babyapi is also able to create a client that provides access to the base endpoints:

// Create a client from an existing API struct (mostly useful for unit testing):
client := api.Client(serverURL)

// Create a client from the Resource type:
client := babyapi.NewClient[*TODO](addr, "/todos")
// Create a new TODO item
todo, err := client.Post(context.Background(), &TODO{Title: "use babyapi!"})

// Get an existing TODO item by ID
todo, err := client.Get(context.Background(), todo.GetID())

// Get all incomplete TODO items
incompleteTODOs, err := client.GetAll(context.Background(), url.Values{
    "completed": []string{"false"},
})

// Delete a TODO item
err := client.Delete(context.Background(), todo.GetID())

The client provides methods for interacting with the base API and MakeRequest and MakeRequestWithResponse to interact with custom routes. You can replace the underlying http.Client and set a request editor function that can be used to set authorization headers for a client.

Testing

babyapi also makes it easy to unit test your APIs with functions that start an HTTP server with routes, execute the provided request, and return the httptest.ResponseRecorder.

Storage

You can bring any storage backend to babyapi by implementing the Storage interface. By default, the API will use the built-in MapStorage which just uses an in-memory map.

The babyapi/storage package provides another generic Storage implementation using madflojo/hord to support a variety of key-value store backends. babyapi/storage provides helper functions for initializing the hord client for Redis or file-based storage.

db, err := storage.NewFileDB(hashmap.Config{
    Filename: "storage.json",
})
db, err := storage.NewRedisDB(redis.Config{
    Server: "localhost:6379",
})

api.SetStorage(storage.NewClient[*TODO](db, "TODO"))

Examples

Description Features
TODO list This example expands upon the base example to create a realistic TODO list application
  • Custom PATCH logic
  • Additional request validation
  • Automatically set CreatedAt field
  • Query parameter parsing to only show completed items
Nested resources Demonstrates how to build APIs with nested/related resources. The root resource is an Artist which can have Albums and MusicVideos. Then, Albums can have Songs
  • Nested API resources
  • Custom ResponseWrapper to add fields from related resources
Storage The example shows how to use the babyapi/storage package to implement persistent storage
  • Use SetStorage to use a custom storage implementation
  • Create a hord storage client using babyapi/storage
TODO list with HTMX UI This is a more complex example that demonstrates an application with HTMX frontend. It uses server-sent events to automatically update with newly-created items
  • Implement babyapi.HTMLer for HTML responses
  • Set custom HTTP response codes per HTTP method
  • Use built-in helpers for handling server-sent events on a custom route
  • Use SetOnCreateOrUpdate to do additional actions on create
  • Handle HTML forms as input instead of JSON (which works automatically and required no changes)
Event RSVP This is a more complex nested example that implements basic authentication, middlewares, and relationships between nested types. The app can be used to create Events and provide guests with a link to view details and RSVP
  • Demonstrates middlewares and nested resource relationships
  • Authentication
  • Custom non-CRUD endpoints
  • More complex HTML templating
Multiple APIs This example shows how multiple top-level (or any level) sibling APIs can be served, and have CLI functionality, under one root API
  • Use NewRootAPI to create a root API
  • Add multiple children to create siblings

Also see a full example of an application implementing a REST API using babyapi in my automated-garden project.

Contributing

Please open issues for bugs or feature requests and feel free to create a PR.

babyapi's People

Contributors

calvinmclean avatar cody-code-wy avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.