mirror of
https://github.com/BradNut/TofuStack
synced 2025-09-08 17:40:26 +00:00
92 lines
4.2 KiB
Markdown
92 lines
4.2 KiB
Markdown
# Sveltekit - Taro Stack
|
|
|
|
## ❗ Important
|
|
|
|
If you forked this repository before May 27th, you'll want to view commit `653e2c2`. There was an issue with the Hono context
|
|
not correctly parsing routes.
|
|
|
|
## ❔ What
|
|
|
|
A scalable, testable, extensible, boilerplate for Sveltekit.
|
|
|
|
Sveltekit is awesome. File-based routing, SSG/SSR, and having the ability to have a backend attatched to your frontend saves incredible amounts of time and effort.
|
|
|
|
But the default backend sometimes isn't enough. There are some projects that require more powerful and feature rich backends. I'm talking Middleware, guards, pipes, interceptors, testing, event-emitters, task scheduling, route versioning, and so on.
|
|
|
|
So what I've done is attatched Hono, a fully fletched backend, to run on the Sveltekit process and forward all API requests to it.
|
|
|
|
`/api/[...slugs]`
|
|
|
|
```ts
|
|
import app from '$lib/api';
|
|
import type { RequestHandler } from '@sveltejs/kit';
|
|
|
|
export const GET: RequestHandler = ({ request }) => app.fetch(request);
|
|
export const PUT: RequestHandler = ({ request }) => app.fetch(request);
|
|
export const DELETE: RequestHandler = ({ request }) => app.fetch(request);
|
|
export const POST: RequestHandler = ({ request }) => app.fetch(request);
|
|
```
|
|
|
|
## Features
|
|
|
|
- 🟢 Full E2E typesafety
|
|
- 🟢 RPC Client for API Requests
|
|
- 🟢 Custom Fetch Wrapper
|
|
- 🔴 Deployment Template
|
|
- 🟠 Authentication
|
|
- 🟢 Email/Passkey
|
|
- 🔴 OAuth
|
|
- 🟢 Email Update/Verifiaction
|
|
|
|
|
|
## Technologies
|
|
|
|
- [Lucia](https://lucia-auth.com): Hits the right level of abstraction for me. Hand me the tools to build a secure authentication system and let me implement it to suite my needs
|
|
- [Drizzle](https://orm.drizzle.team/) - Drizzle advertises itself as an ORM but I think its deceptive. Its a query builder with a migration client. Everytime I've used an ORM, I find myself fighting it for sometimes the simplist of use cases. Drizzle just gives you type-safety while querying SQL in a native fashion. Learn SQL, not ORMs.
|
|
- [Hono](https://hono.dev/): Fast, lightweight, and built on web standards; meaning it can run anywhere you're Sveltekit app can. It's essentially a better, newer, and ironically more stable Express.JS. This provides us an extreemely good foundation to cleanly build ontop of without having to teardown first. It has a zod adapter for validating DTO's which can be shared with the frontend too.
|
|
- [Sveltekit](https://kit.svelte.dev/): After trying Vue, React, Next, and pretty much every frotnend framework in the JS ecosystem, its safe to say I vastly prefer Svelte and its priority of building on web standards.
|
|
|
|
## Architecture
|
|
|
|
There are a few popular architectures for structuring backends. Technical, Onion, VSA, and the list goes on. I almost always choose
|
|
to start with Technical and let the project naturally evolve into one of the others.
|
|
|
|
### Folder Structure
|
|
* **controllers** - Responsible for routing requests
|
|
|
|
* **services** - Responsible for handling business logic.
|
|
|
|
* **repositories** - Responsible for retrieving and
|
|
storing data.
|
|
|
|
* **infrastructure** - Handles the implementation of external services or backend operations.
|
|
|
|
* **interfaces** - Common
|
|
|
|
* **middleware** - Middlware our request router is responsible for handling.
|
|
|
|
* **providers** - Injectable services
|
|
|
|
* **dtos** - Data Transfer Objects (DTOs) are used to define the shape of data that is passed.
|
|
|
|
* **common** - Anything commonly shared throughout the backend
|
|
|
|
|
|
### File Naming
|
|
You might notice how each file in the backend is postfixed with its architectural type(e.g. `iam.service.ts`). This allows
|
|
us to easily reorganize the folder structure to suite a different architecture.
|
|
|
|
For example, if you want to group folders by domain(DDD), you simply drag and drop all related files to that folder.
|
|
```
|
|
└── events/
|
|
├── events.controller.ts
|
|
├── events.service.ts
|
|
└── events.repository.ts
|
|
```
|
|
|
|
|
|
## Testing
|
|
|
|
Testing probably isn't first and foremost when creating an app. Thats fine. You shouldnt't be spending time writing tests if your app is changing and pivoting.
|
|
|
|
BUT a good stack should be **testable** when the time to solidify a codebase arrives. I created this stack with that pinciple in mind. I've provided a examples of how to write these tests under `authentication.service.test.ts` or `users.service.test.ts`
|