Tahul / nuxt-edgedb

💽 Nuxt 3 integration for EdgeDB
71 stars 7 forks source link

CRUD Operations #11

Open Tahul opened 11 months ago

Tahul commented 11 months ago

We could supply a defineEdgeDbHandler function that could be used to wrap query builder methods:

// /server/api/blogpost.ts
const q = useEdgeDbQueryBuilder()

export default defineEdgeDbHandler(
   q.BlogPost,
   {
      // /api/blogpost GET
      select: async (blogPost, req) => {
         // blogPost would be the data returned from the query build upon operation

         // return of this function would be alterable if that function is defined

         // if the function return is undefined, then the `blogPost` will be returned

         // if the function returns something, then it will replace original return type

        // the `select` as it is `GET` would support query parameters from `q.select()` via query parameters
      }
      // /api/blogpost POST
      create: async (blogPost, req) => {
         // the `create`, `update`, `delete` would support passing properties and links via JSON body
      },
      // /api/blogpost PATCH
      update: async (blogPost, req) => {
        ...
      },
      // /api/blogpost DELETE
      delete: async (blogPost, req) => {
         ...
      }
   }
)

I guess it would also automatically support auth as req would automatically be passed to client used in the background.

WDYT @juni0r ?

juni0r commented 11 months ago

I see where you're heading, essentially creating controllers. Drawing from experience however, this can get out of hand quickly. These CRUD-controllers work very well with simple cases like one model/type per controller, no authorization logic, etc. That works mostly fine for an admin backend, for instance, but tend to be too genric for many cases.

So you end up adding all kinds of hooks and options to tend to all kinds of specific requirements of applications. Then you'll want nested routes, for example, or other features that quickly add a lot of complexity. I used a similar library with Ruby on Rails. As the application grew, it became increasingly difficult to figure out what exaclty happened in a controller, especially when it's behavior was highly customized. We ended up ditching the CRUD-controllers and create custom ones. There was a good deal of (structural) duplication involved but it became very straightforward to figure out what precisely happens in any given route. In another refactoring pass we extracted some common patterns to mitigate duplication without sacrificing the expressiveness of the code.

Also, I haven't built a sizeable API with Nuxt yet, nor do I have any practical experience with EdgeDB so far, which makes it very difficult for me to generalize. My approach would be to build one or two actual applications, get a feeling for what works and what doesn't. As soon as I've got that figured out, I'd start creating abstractions.

There are still a few kinks in the module that need to be ironed out and I'd put grander ideas on hold until that's accomplished and focus on getting basic but solid support for EdgeDB towards an 1.0 release.