camelCase and Supabase naming consitency
I have this monorepo project with passed MVP phase with success and now we are thinking of reorganizing typescript types. I am looking at supabase autogenerated types and looks very appealing but I am wondering how to use them considering that we want to keep camelCase across the project.
Right now we have all types defined with camel case and we use two utilities (toCamelCase and toSnakeCase) for interacting with supabase.
Is there a good practice how do handle this?
Or is it a good idea to keep snake_case types?
8 Replies
Supabase generated types are based on the database table names which are
snake_case
. Your own code can continue to use whichever casing format it want's to use, it doesn't affect anything in the project really.yeah but I was wondring is there is a solution that people use that proved to be ok in the long run. i know there is no right or wrong, but there are many options like:
- stiking just with non generated types
- using supabase generated types and make some mapping utility
- leave supabase types as they are (snake_case = db fields) and keep other application types came cased
- etc
I`m researching for best option consindering that we already made a mess once (understandable at that time) and now I want to choose a good stardard and stick to it
I tend to do a mix of both
snake_case
and camelCase
in my projects. It would be a waste of time trying to remap the Supabase generated types for me so I just let it do what it does and make all my own types camelCase
. I guess this is a good way to differentiate between generated types and those written by myself.come to think about it, i kind of agree. what do you do when you need to extend a supabase type. just add the properties in the extension camel cased?
This is what I've done in the past https://github.com/silentworks/supabase-by-example/blob/main/nextjs/app/global.d.ts#L7
Additional properties are normally database columns so I just add them in the case they already are in.
Initially, like yourself, I started with helper functions for converting between the cases, and since they were implemented in the defining functions, I would call them without having to think about it. Eventually, I came to use the same approach as @silentworks suggest.
I've now moved away from that too, and started using [updatable] views (which is also what PostgREST recommends). I've aliased the columns in the view to use camelCase. This is also how I distinguish between working with views and underlying tables (which for the most parts are already hidden from the Data API).
PostgREST 13.0
Schema Isolation
A PostgREST instance exposes all the tables, views, and functions of a single PostgreSQL schema(a namespace of database objects). This means private data or implementation details can go inside different private schemas and be invisible to HTTP clients. It is recommended that you don’t expose tab...
Do you have some code example of what you are now doing here? I would like to see how you are aliasing the columns in your views, are you using generated columns instead? also isn't this creating an maintenance burden?
Sure thing.
I am defining the variables here for illustrative purposes. Typically, I would have an array with these maps already set, but I want to show the convenient of not having to use
key: value
notation.
Supabase will automatically generate the types (see screenshot).
also isn't this creating an maintenance burden?Not AFAIK. I am already making extensive use of views to minimize data exposure. And embracing the PostgREST philosophy of viewing views as API endpoints (rather than PostgREST being a mere interface for interacting with the database) feels more natural. I also keep my views as simple as possible to keep them updatable without having to rely on
INSTEAD OF
triggers.