A project template using clojure, clojurescript, reitit, inertiajs, chakra-ui, playwright, postgres, fly.io and capacitorjs. Heavily inspired by Michael Sahili's version of PingCRM and using inertia-clojure.
GoodPlace attempts to be a project that forms a good starting point for simple, high quality web applications. It follows a Backend for Frontend approach facilitated by inertiajs, we disregard REST, GraphQL et al in favour of inertia's simple model of returning data for a given page either within the rendered html or a simple json payload depending on how it's loaded (read more in inertia's documentation). It still allows us to use modern js frameworks to build components and frontend behaviour.
It's definitely a young project so there might be rough edges, please file and issue if you have trouble running things.
It's common to see clojure code bases with frontend and backend parts share the same space and sometimes even the same deps file. This can be tricky and lead to a lot of conditional behaviour. IMO it's better to keep different things completely separate and share explicitly when required.
The shared directory contains all the application routes that are used amongst other things, and we can join our relevant backend handlers and frontend components to them easily whilst maintaining a consistent repository of what routes are avaiable in one place.
There are some distinct types of route to be aware of within inertia:
- A plain page component, which we can tell inertia to render with no additional data required
- A page with data, in our server handler we will need to supply props to be used by the page component and use the
usePage
hook to retrieve - A route with no corresponding page, typically non-GETs, we can return a redirect response 303 with any necessary data added to flash data for the page
- Add it to
goodplace.shared.routes
- Depends on the type of page or route
- For a plain page you can:
- add a page component, maybe in
goodplace.pages.<something>
- add a join to your new component via
goodplace.pages/page-components
- add an entry to
goodplace.handlers/handlers
for the same id, it can just use(inertia-handler <id>)
- add a page component, maybe in
- For a page and a route you can follow the steps for a page but add additional handlers for other methods
- For a route with no corresponding page you can add the handlers
- For a plain page you can:
- Inertia caches root components so you may need to refresh to see changes (correct me if I'm wrong)
- Add easy running of cljs, js parts
- Add authentication for routes
- Add basic tests
- Add user management
- Reimplement cljs friendly hooks for inertia
- Fork out inertia wrapping into new library
- Add titles to pages
- Produce jar of application
- Deployment (fly.io)
- Improve error feedback development time
- Add local postgres
- Separate handlers into namespaces
- Use postgres for notes too
- Remove old sqlite implementations
- Fix broken symbols in prod
- Use production postgres
- Separate pages into namespaces
- Mobile/Responsive views
- CapacitorJS?
- Improve tests
- Reduce bulk of pages namespaces
- Improve documentation
- High Level Description
- Improve appearance of side menu
- Import database changes
- Ensure we don't scrap the database on every reset
- Import logging changes
- Import authorization changes
- Import malli validation
- Maybe fix hotloading?
- Create a dashboard-like page
- Create a scaffolder for new routes
- Create a generator that can produce copies of this app elsewhere
- Improve build
- Improve usability
- Out of the box run test
- Add rationale for GoodPlace
- CI tests (Github Actions)
- Add individual pages for server errors