Live data from Hacker News

Supabase (YC S20) – An open source Firebase alternative

supabase.io

291–300 of 374 posts

Re: Supabase (YC S20) – An open source Firebase alternative

#291
post #149

Disclaimer: I work on Firebase but I'm always speaking for myself on Hacker News. This looks really cool! Honestly I think the Firebase comparison may be throwing some people off here because this is a SQL-based system, which means there's a huge base of existing tools/techniques/knowledge to build from. I like any tool which makes it easier to build an app. It's 2020 and we still start every app like this: * Pick a…

> Honestly I think the Firebase comparison may be throwing some people off here because this is a SQL-based system You're correct - we're building on top of Postgres so it's not a perfect comparison. And we're a bit early to even make it a fair claim. I'm glad the crowd here has been so receptive. We were planning of launching in September, but it must have been picked up somewhere on the internet (thanks @habosa)

Just a counter datapoint, the Firebase comparison is what got me to click on the link and check it out. I'm a huge Firestore fan... here's what would get me to try something new:

- Better user permissions, ability to actually see my users and user permissions in a UI

- Better ability to choose conflict resolution logic

- Tied to that, ability to get "patches" from the server... right now if a change happens in my Firestore document, the server sends the entire document to the client. I'd love to be able to get a patch with just the changed data (and of course send patches to the server too, which it looks like you would support).

- Join queries to save me from needing to do multiple client -> server trips. If it's SQL I'm guessing you would support this.

Very interesting project! I'll be following your progress.

Re: Supabase (YC S20) – An open source Firebase alternative

#292

Earlier quoted context omitted.

To me there's a sliding scale between productivity, where you use a heavy framework like Django and Rails to do everything for you, and control, where you write boilerplate to stitch all your favorite single-purpose libraries together using your preferred patterns. They each have their purposes. Django will get you to market fast with all the features you need, and keep you there for a long time. But it forces (throu…

So just don't use fat models. The only sensible way to use Django is to put all the business logic in service methods, not in models/managers or serializers/forms. If all your business logic is in models then of course your app is going to be completely unmaintainable and it's going to take developers weeks to do things that should normally take a couple hours. There is definitely a real problem in the Django communi…

Completely agree!

Re: Supabase (YC S20) – An open source Firebase alternative

#293
post #184

Earlier quoted context omitted.

Perhaps what they meant is it requires application code (server or severless) for business logic mutations, instead of surfacing database functions as RPC. This was the particular reason I moved away from Hasura. Business logic mutations in SQL are too powerful to give up and replace with JavaScript in opinion.

I believe Hasura is working towards being able to write Actions in SQL. How are you surfacing RPCs from the database? That sounds interesting.

A key insight I've arrived at over past few months is GraphQL is most useful for multiple teams to have "one" API endpoint and they can then work on front end features without blocking each other, as well as write different clients (and therefore many different possible "queries") without having to constantly re-write the back-end API. In other words, ultimate flexibility on the front end when you don't know what queries you need and you need to divide work across teams/developers.

This comes at the cost of complexity of implementing a performant GraphQL server. Perhaps another instance of a thing that gets really popular because it's good for large corporations rather than being ideal for solo devs or small projects. Like NoSQL and other scalability optimizations vs sql etc. Hasura seems the best I've come across so far at making this easy/quick.

But in many situations, at least for my use-case and likely many others, simply writing well thought out SQL queries are both simple, easily iterated upon, require fewer layers, infrastructure, code etc. In the Hasura scenerio, custom SQL queries inevitably are needed anyways, Hasura mostly gets you the "crud" operations quickly.

If you construct your "screens" or "pages" of a Next.js web-app, for example, as collection of RPC's defined in SQL either requested through "/api" routes integrated with the framework, or even better (when possible) directly accessing your database calls [using raw sql of course] within component "getServerSideProps" and "getStaticProps" calls[0], there isn't really anything simpler in my view. No ORM, no Graphql.

By RPC, I simply mean a stored sql function, or view. Executing this is as simple as:

  // some api endpoint, which then queries database:

  await db('select pay_balance($1)', [leaseId]);
  return res.status(200).send("ok");
The stored function is written in SQL, not javascript http requests, and has full access to all the data in the database to implement transformations on this data.

Reading "The Art of Postgresql"[1] currently and a constant refrain is to push as much business logic into the database as possible. When you do this, you avoid so much complexity vs having this spread around in application code or cloud functions or microservices, etc. ACID, transactions, etc. all come with it.

[0] https://twitter.com/adamwathan/status/1246144545361997829 this uses a query builder, I wouldn't even do that. Just raw sql everywhere.

[1] https://theartofpostgresql.com/

The tagline: "Turn thousands of lines of code into simple queries" couldn't be more impactful in my thinking of late, and it's been extremely beneficial for making me more productive with simpler, less error prone code.

Re: Supabase (YC S20) – An open source Firebase alternative

#294

Earlier quoted context omitted.

So just don't use fat models. The only sensible way to use Django is to put all the business logic in service methods, not in models/managers or serializers/forms. If all your business logic is in models then of course your app is going to be completely unmaintainable and it's going to take developers weeks to do things that should normally take a couple hours. There is definitely a real problem in the Django communi…

Completely agree!

I’m writing a Django style guide since all the existing ones are bad. If you send me an email then I’ll send you a draft, so that you have something to show your coworkers.

Re: Supabase (YC S20) – An open source Firebase alternative

#295

From what can be understood: Writing a backend with Supabase will turn into managing all these servers. Backend Server = Supabase (for realtime) + PostgREST (for REST APIs) + Serverless Functions (for business logic) + Postgres SQL database. For somebody using Firebase today, How will this solution with Supabase be simple to manage and scale ? Help me understand if I am wrong.

We plan to make the self-hosting a lot easier/simpler, it's on the roadmap. This post caught us a bit by surprise - we planned to launch later this year with better documentation and opensource suppport. Basically: we will bundle everything into a single deploy (docker, AWS, DO, etc).

Got it. But that is a lot to make it work seamlessly.

How do you plan to make any business out of this ?

Re: Supabase (YC S20) – An open source Firebase alternative

#296

Earlier quoted context omitted.

In Hasura your still need a 3rd party service such as Firebase or 0Auth for Authentication. Also, it depends on Serverless functions for doing any business logic.

This is a misconception. Hasura doesn’t depend on serverless functions for doing business logic. If you are comfortable writing GraphQL, you can add your own custom GraphQL server to Hasura for business logic. If you are comfortable with REST APIs (or something that already exists), you can use Hasura Actions to define GraphQL types and call your REST endpoint to perform business logic. Now where this server is hoste…

> you can add your own custom GraphQL server to Hasura for business logic

> If you are comfortable with REST APIs (or something that already exists)

This is an order of magnitude worse than simply having to "depend on serverless functions". You're saying for any real-world business logic (read: non-crud writes to the database, every app has these), you need to re-implement another graphql server? or simply have something that "already exists" to solve your problem? Isn't that what Hasura is for?

> Now where this server is hosted is totally upto the user.

I think the dream of Hasura-like products is to not have a bunch of servers everwhere that need to be managed and coordinated. This is the beauty and power of Postresql. Containing our business logic in it is ideal. At the very least, containing our business logic in 1 Hasura instance would be 2nd best. Calling out to some other rest api or custom implemented GraphQL server defeats the purpose of a self-contained GraphQL layer. If some of the data lives elsewhere, sure. But what if the data just lives in our database?

Re: Supabase (YC S20) – An open source Firebase alternative

#297

Earlier quoted context omitted.

Can you provide a more detailed critique of Django’s “Fat Models” recommendation? How would you prefer to manage this logic?

TL;DR Django models are the database, which makes them the wrong choice for presenting a service-layer interface to the persistence. They are inherently unable to hide, encapsulate, and protect implementation details from consumer that don't care or shouldn't be allowed to access. The Django model is a representation of the database state. It's an infrastructure-layer object. It's is _very_ tightly coupled to the dat…

We started moving off "fat models" at my job and onto DDD (service methods, entities, etc.), and I have to say after a year I'm not a fan. Here are my beefs:

1. If you're not using models, it's a lot of work to stay fast.

If you've got a Customer instance, and you want to get customer.orders, you've got a problem if it's not lazy. If it's a queryset, you get laziness for free, if it isn't you have to build it yourself. God help you if you have anything even remotely complicated. You also need trapdoors everywhere if you want to use any Django feature like auth, or Django libraries.

2. You have to build auth/auth yourself

Django provides really nice auth middleware and methods (user_passes_test).

3. Service methods only do things something else should be doing.

You might be doing deserialization, auth/auth checks, database interactions, etc. All of that stuff belongs at a different layer (preferably abstracted away like @user_passes_test or serializers).

4. The model exposed by Django and DRF is actually pretty good, and you'll probably reimplement it (not as well)

The core request lifecycle is:

request -> auth -> deserialize -> auth -> db (or other persistence stuff) -> business stuff -> db (or other persistence stuff) -> serialize -> response

We've reimplemented all of those layers, and since we built multiple domains we reimplemented some of them multiple times. It probably would've been better to just admit "get_queryset" and the like are good ideas.

5. Entities are a poor substitute for regular objects and interfaces.

We've mostly ended up wrapping our existing models in entities, but just not implementing most of the properties/fields/attributes/methods. But again, we have to trapdoor a lot, we have trouble with laziness and relationships in general, and we have a lot of duplicate code in our different domains.

6. We have way too many unit tests.

Changing very small things requires changing between 5-10 tests, each of which use mocks and are around a dozen lines at least. Coupled with the level of duplication, this has really slowed us down. They also take _forever_ to run.

FWIW I think you're right about jamming too much into models; I think that works at a small scale but really breaks down quickly. I think at this point, my preferences are:

1. Ideally, your business logic should be an entirely separate package. It shouldn't know about HTML, JSON, SQL, transactions, etc. This means all that stuff (serialization, persistence) is handled in a different layer. Interfaces are your friend here, i.e. you may be passing around something backed by models, but it implements an interface your business logic package defines.

2. The API of your business logic package are the interfaces you expose and document. The API of your application is your REST/GraphQL/whatever API--that you also document.

3. Models should be solely database-specific. If you're not dealing with the database and joins and whatever, it doesn't go in models and it doesn't go in managers.

4. Don't make a custom user model [1].

5. Serialization, auth, and persistence should be a declarative and DRY as possible. That means class-level configuration and decorators.

6. Bias strongly against unit tests, and rely more strongly on integration tests. Also consider using them during development/debugging, and removing them when you're done.

Does that seem reasonable to you? I spend a lot of time thinking about this stuff, and I would like my life to be less about it (haha) so, any insight you can give would be super appreciated.

[1]: https://docs.djangoproject.com/en/3.0/topics/auth/customizin...

Re: Supabase (YC S20) – An open source Firebase alternative

#298

Earlier quoted context omitted.

Rails is probably one of the best ways to not waste time. I knew they had some of this capability but I wasn't sure if they generated the whole controller, fully hooked up to the models, too. The only thing that turns me off about Rails and .NET is that it's a big learning curve _because_ the projects are so feature complete. Since I haven't worked professionally in either of them, I haven't been able to get myself t…

Agreed, this is a real problem. I recently did a test. I have about a year of rails experience but it was so long ago that I forgot most things and had to look them up. I also wrote quite a bit of node/express but it was in the node 0.10 days so I had a lot of catch-up to do. I started a new app and I got a basic Users and Sessions model with endpoints running (I like this test because dealing with passwords and API…

If you would like to explore more TypeScript ORM Libraries TypeORM comes to mind, and recently Zapatos made it into the frontpage and although it's new it looks like a nice simple but powerful alternative, much more close to raw SQL than TypeORM's clearly abstract layer/magic sause.

just my 2 cents

Also about more general web frameworks like rails and not ORM's I personally use NextJS with TypeScript, like Ant.Design for it's react components library, use Jest for testing + Eslint + Prettier.

That makes the most of my IDE, it's like having a second pair of eyes behind you in Real Time telling you every typo between Types, Linting, and other VSCode extension goodies...

Re: Supabase (YC S20) – An open source Firebase alternative

#299
post #279

I am ecstatic that someone is finally taking on Firebase. As a Firebase user, I find it invaluable. Their free plan and limits are very generous. The fact they offer not only a database, but authentication, hosting and perhaps one of their biggest features besides authentication: Firebase Functions. I have API's in deployment that are solely running using Firebase Functions and using Firestore as the database. The CL…

I've been using Firebase since 2016 in production and after all these years I find the service quite lacking. Both databases are super limited and put all the burden of work to the client(s) for anything beyond very simple queries. The functions have some of the worst cold starts I've experienced. Until very recently the dev experience was terrible but Firebase local dev was released a couple of days ago so this shou…

FWIW, the cold start issue (which was hitting me with regular 10-30+ second delays for even the simplest of functions) has recently been "fixed" (at least, I'm down to The specific issue I was running into: https://github.com/googleapis/google-cloud-node/issues/2942

Re: Supabase (YC S20) – An open source Firebase alternative

#300

Earlier quoted context omitted.

TL;DR Django models are the database, which makes them the wrong choice for presenting a service-layer interface to the persistence. They are inherently unable to hide, encapsulate, and protect implementation details from consumer that don't care or shouldn't be allowed to access. The Django model is a representation of the database state. It's an infrastructure-layer object. It's is _very_ tightly coupled to the dat…

We started moving off "fat models" at my job and onto DDD (service methods, entities, etc.), and I have to say after a year I'm not a fan. Here are my beefs: 1. If you're not using models, it's a lot of work to stay fast. If you've got a Customer instance, and you want to get customer.orders, you've got a problem if it's not lazy. If it's a queryset, you get laziness for free, if it isn't you have to build it yoursel…

I think we're agreeing on the majority of this. We have not chucked DRF or Django auth or anything. We've just created service layers to take the business logic out of the API views, API serializers, and DB models.

Each action looks like

1. Request arrives into the app, auth happens using DRF on the API view. This is all using Django & DRF built-ins.

2. In the API view: request data gets serialized using DRF serializers, but no calculated fields or model serializers or other BS. JSON -> dict only. The dict does not have models in it, only IDs: profile_id, reservation_id, whatever. Letting the "model Serializers" turn a JSON location ID into a Location model is how you get 10 database queries before you've done _anything_. At this point we don't care if the location_id is valid. We are just serializing.

3. Still in the API view: Dict dump from the serializer gets shoved into whatever format you're going to send to the service layer. For us this is often an attrs/dataclass. If we're calling the "Reservations Service" method "create reservation", we pass in location_id, start time, end time, and the User model. The User model in this case is breaking our policy of not passing models through the service boundary, but it's the one exception for the entire code base, because it's too useful not to take getting it for free from DRF's user auth. We would be basically throwing it away then re-calling for it in the service layer which is dumb.

4. Call the Reservations Service layer. The service layer is going to do n things to try to create the reservation. If it needs to insert related records, like in a transaction, cool. Its job is to provide a sane interface for creating a Reservation, and whatever related side effects, not to only ever touch the Reservation model/table and nothing else. The base of our Domain is Reservation, creating a ReservationReceipt and a ReservationPayment are entirely within scope. Use the Payment model directly to do this if there's zero extra logic to encapsulate, or create a Payment service if you have a ton of Payment-creation logic you need to extract/hide from the Reservation service. You can still manage it all in a transaction if you want. The point is that the caller (the API layer) doesn't see this. It only sees that it's calling the Reservation Service.

5. The Reservation service will either return a dataclass/attrs objects representing a successful Reservation created, or raise a nice business error like ReservationLocationNotFound (remember when you passed in a bad location id to the API, but we didn't want to check it in the API layer?)

6. API View takes the service response & serializes it back, or takes the business error and decides which HTTP error it should be.

Post reply on HN