Skip to content

Commit

Permalink
Improve README and add one for nested example
Browse files Browse the repository at this point in the history
  • Loading branch information
calvinmclean committed Apr 30, 2024
1 parent ed60b70 commit 66c4fb2
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,13 @@ api.SetStorage(storage.NewClient[*TODO](db, "TODO"))
| | Description | Features |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [TODO list](./examples/todo/) | This example expands upon the base example to create a realistic TODO list application | <ul><li>Custom `PATCH` logic</li><li>Additional request validation</li><li>Automatically set `CreatedAt` field</li><li>Query parameter parsing to only show completed items</li></ul> |
| [Nested resources](./examples/nested/) | 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` | <ul><li>Nested API resources</li><li>Custom `ResponseWrapper` to add fields from related resources</li></ul> |
| [Nested resources](./examples/nested/) | 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` | <ul><li>Nested API resources</li><li>Custom `ResponseWrapper` to add fields from related resources</li><li>HATEOAS Extension for hypermedia linking</li></ul> |
| [Storage](./examples/storage/) | The example shows how to use the `babyapi/storage` package to implement persistent storage | <ul><li>Use `SetStorage` to use a custom storage implementation</li><li>Create a `hord` storage client using `babyapi/storage`</li></ul> |
| [TODO list with HTMX UI](./examples/todo-htmx/) | 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 | <ul><li>Implement `babyapi.HTMLer` for HTML responses</li><li>Set custom HTTP response codes per HTTP method</li><li>Use built-in helpers for handling server-sent events on a custom route</li><li>Use `SetOnCreateOrUpdate` to do additional actions on create</li><li>Handle HTML forms as input instead of JSON (which works automatically and required no changes)</li></ul> |
| [Event RSVP](./examples/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 | <ul><li>Demonstrates middlewares and nested resource relationships</li><li>Authentication</li><li>Custom non-CRUD endpoints</li><li>More complex HTML templating</li></ul> |
| [Multiple APIs](./examples/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 | <ul><li>Use `NewRootAPI` to create a root API</li><li>Add multiple children to create siblings</li></ul> |
| [Background Worker](./examples/background-worker/) | This example shows how you can use `babyapi` in an application alongside background workers and have runtime control over all goroutines | <ul><li>Use `WithContext` to add a context to an API so the API will stop when the context is cancelled</li><li>Use `api.Done()` to have other goroutines stop when the API is stopped</li></ul> |
| [sql](./examples/sql/) | This example shows how you can build an API with a custom implementation of `babyapi.Storage` using [`sqlc`](https://sqlc.dev) | <ul><li>Implement an Extension using a custom implementation of `babyapi.Storage`</li><li>Use `api.Done()` to clean up DB resources<li><li>Extend the built-in CLI to add flags or other customizations<li></ul> |
| [SQL](./examples/sql/) | This example shows how you can build an API with a custom implementation of `babyapi.Storage` using [`sqlc`](https://sqlc.dev) | <ul><li>Implement an Extension using a custom implementation of `babyapi.Storage`</li><li>Use `api.Done()` to clean up DB resources</li><li>Extend the built-in CLI to add flags or other customizations</li></ul> |

Also see a full example of an application implementing a REST API using `babyapi` in my [`automated-garden` project](https://github.com/calvinmclean/automated-garden/tree/main/garden-app).

Expand Down
51 changes: 51 additions & 0 deletions examples/nested/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Nested Example

This implements an API where the root resource is an `Artist` which can have `Albums` and `MusicVideos`. Then, `Albums` can have `Songs`.

It demonstrates:
- APIs with nested/related resources
- Custom `ResponseWrapper` which allows a Song response to show Album details
- `extensions.HATEOAS` to easily add hypermedia linking to resources so a user can discover Albums by looking at an Artist and then discover Songs for the Album.


## Try it out!

Run the server
```shell
go run main.go serve
```

Create an Artist
```shell
⟩ go run main.go client \
artists post \
--data '{"name":"artist1"}'
```
```json
{
"id": "coinqaon1e4crs6ambu0",
"links": {
"Albums": "/artists/coinqaon1e4crs6ambu0/albums",
"self": "/artists/coinqaon1e4crs6ambu0"
},
"name": "artist1"
}
```

Create an Album
```shell
⟩ go run main.go client \
albums post \
--artists-id coinqaon1e4crs6ambu0 \
--data '{"title":"album1"}'
```
```json
{
"id": "coinqq8n1e4crs6ambug",
"links": {
"Songs": "/artists/coinqaon1e4crs6ambu0/albums/coinqq8n1e4crs6ambug/songs",
"self": "/artists/coinqaon1e4crs6ambu0/albums/coinqq8n1e4crs6ambug"
},
"title": "album1"
}
```

0 comments on commit 66c4fb2

Please sign in to comment.