SERVER / FILE MODEL

Six responsibilities, one request path

main.dowe activates the server. Endpoint modules map HTTP methods and paths, middleware controls access, handlers own the HTTP boundary, functions own reusable logic, and config modules expose server-only resources.

Follow the request from main.dowe to endpoints, handler, service, and repository. Each file should make one authority obvious.
File or declaration
Owns
What belongs there

No data

There are no records to display

PROJECT SHAPE

Organize the backend by responsibility

This tree is recommended because it makes security and ownership visible. Imported modules are classified by their declarations, not by their folders, but new backend source should stay under server.

dowe
main.dowe
.env.example
.env
server/
  endpoints.dowe
  handlers/
  middlewares/
  config/
  services/
  repositories/
  providers/
  tasks/
  utils/
  types/
  entities/
  seeders/
  migrations/
Boundary
Rule

No data

There are no records to display

CONNECTED EXAMPLE

Follow one request through the backend

These six files expose GET /api/blogs. The HTTP boundary stays thin, the service coordinates the use case, and the repository is the only function that reads Database.

Read each example from top to bottom. The import in one file explains why the next file is part of the request path.

1 / main.dowe

Activate the imported endpoint graph

The root file chooses the server port and connects the endpoint declaration that owns the HTTP routes.

dowe
import ApiRoutes from "@/server/endpoints"

main
  server port:8080
    endpoints:ApiRoutes

2 / server/endpoints.dowe

Map the method and path

The endpoints declaration joins a URL to the handler imported from the handlers folder.

dowe
import listBlogs from "@/server/handlers/blogs-handler"

endpoints ApiRoutes
  group path:"/api/blogs"
    get path:"" handler:listBlogs

3 / server/handlers/blogs-handler.dowe

Choose the HTTP response

The handler is the HTTP boundary: it calls the use case and serializes the value as JSON.

dowe
import listBlogsService from "@/server/services/blogs-service"

handler listBlogs
  listBlogsService blogs
  return json:{ ok:true data:blogs }

4 / server/services/blogs-service.dowe

Coordinate the use case

The service connects the handler to reusable business logic without returning an HTTP response.

dowe
import listBlogsRepository from "@/server/repositories/blogs-repository"

fn listBlogsService
  listBlogsRepository blogs
  return value:blogs

5 / server/repositories/blogs-repository.dowe

Own the Database operation

The repository imports the configured handle, executes the query, and returns a value to the service.

dowe
import AppDb from "@/server/config/database"

fn listBlogsRepository
  query blogs conn:AppDb.list table:"blogs"
  return value:blogs

6 / server/config/database.dowe

Export the server-only connection

Configuration owns credentials and connection details. Other server modules import the handle instead of rebuilding it.

dowe
database AppDb:
  provider:"dowe"
  host:env.DATABASE_HOST
  port:env.DATABASE_PORT
  account:env.DATABASE_ACCOUNT
  secret:env.DATABASE_SECRET
  name:env.DATABASE_NAME
  entities:[]
  seeders:[]

MIDDLEWARE BOUNDARY

Authorize before business logic runs

Middleware belongs on a group, HTTP method, or WebSocket. It either calls next, optionally adding server-only context, or returns a response that prevents the handler from running.

1 / server/middlewares/require-bearer.dowe

Stop unauthorized requests

This middleware validates the bearer token, adds the subject to trusted request context, or returns a 401 before the handler runs.

dowe
middleware requireBearer
  bearer token value:req.header.Authorization
  jwt verified secret:env.JWT_SECRET algorithm:"HS256" token:token
  if verified.valid
    next context:{ auth:{ subject:verified.claims.sub } }
  return status:401 json:{ ok:false error:"Unauthorized" }

2 / server/endpoints.dowe

Attach the policy to a route

The endpoint declares the middleware on the method, so only this protected request passes through requireBearer.

dowe
import requireBearer from "@/server/middlewares/require-bearer"
import createBlog from "@/server/handlers/blogs-handler"

endpoints ApiRoutes
  group path:"/api/blogs"
    post path:"" handler:createBlog middleware:[requireBearer]
Handlers and middleware return HTTP values with return status:... json:.... Reusable fn declarations return values with return value:.... Do not add async, await, assignment syntax, or return response.

DECISION GUIDE

Create the file that owns the authority

Keep the HTTP edge, use-case coordination, data access, integrations, and shared resources separate so security decisions remain visible.

Change
Owner
Where to put it

No data

There are no records to display