For web apps (not simple pages), developed by a single full-stack developer, I think the best solution currently is to use Remix's loaders + actions (i.e. no need to create separate API layer) with EdgeDB (EdgeQL is like GraphQL but with capabilities of SQL, and the DB itself has authn+authz baked-in).
Agree! Came here to give props to EdgeDB. Completely removes the API layer if used with something like SvelteKit. Everything defined in their schema language which then generates typed clients for you.
In my experience the use case is not limited to a single full-stack developer - this approach has turned our entire polyglot team into full-stack devs — no one is afraid of the data layer now. Super refreshing.
For public facing endpoints, "exposing an OpenAPI 3.0+ compliant JSON REST API" would be the first thing I'd reach for.