You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This would be a new project entirely independent but compatible with Wildcard.
This is ambitious and I'm not sure if/when I'll finish this.
In case you ask yourself why this is necessary in the context of Wildcard: it's basically for large scale applications that need to decouple the development of several frontends from the backend development. For most users, Wildcard alone is enough.
A preview:
// Browser-side// Note how we only depend on Wildcard here.import{server}from'@wildcard-api/client';// The query syntax is JSON-like.constposts=awaitserver.query({_table: 'posts',authorId: {_table: 'users',id: '*',username: 'brillout',},title: '*',content: '*',});assert(posts[0].title==='Introducing a new query language');assert(posts[0].content.startsWith('When GraphQL was announced I was super excited but after the honeymoon'));// Similarly for upserting dataawaitserver.query({_table: 'posts',authorId: 'brillout',title: 'NQL + Wildcard = <3',content: 'WIP',});// There is a field with '*' => data retrieval// No field with '*' => data mutation
Resolvers + Wildcard integration
const{ server }=require('@wildcard-api/server');const{ resolveQuery, addResolver }=require('nql');server.query=asyncfunction(query){const{ data }=awaitresolveQuery(query);returndata;};// One resolver per table for data retrievaladdResolver('posts',async(selectFields,filterFields)=>{// A trick is that `filterFields[fieldName]` is always an array.// This solves the N+1 problem!assert(!filterFields.id||filterFields.id.constructor===Array);// (No SQL injection, everything is sanitized.)constres=awaitdb.sql([`SELECT ${selectFields.join(', ')} FROM posts`,// Do this for every `key in filterFields`.`WHERE id IN (`${filterFields.id.map(id=>`'${id}'`).join(', ')})`,].join(' '));returnres;});// One resolver per table is enough for any graph-like query.// With no N+1 problem.
With "object-level permissions":
const{ server }=require('@wildcard-api/server');const{ resolveQuery, addPermissions }=require('nql');server.query=asyncfunction(query){// We need the context for permissionsconstcontext=this;const{ data, permissionDenied }=awaitresolveQuery(query,context);if(permissionDenied){return{ permissionDenied };}else{return{ data };}};// We define permissions programmatically.// This is simple and powerful.addPermissions('read',({object, context})=>{const{ isAdmin }=context.user;// Admins can read everythingif(isAdmin){returntrue;}// Anyone can read everything from the `posts` tableif(object._table==='posts'){returntrue;}// Fine grained permission: anyone can read everything from// the `users` table except for the `password` field.if(object._table==='users'){if(object.password){returnfalse;}else{returntrue;}}// Anything else is forbiddenreturnfalse;});addPermissions('write',({object, context})=>{// Same than above but for mutation});
The text was updated successfully, but these errors were encountered:
This would be a new project entirely independent but compatible with Wildcard.
This is ambitious and I'm not sure if/when I'll finish this.
In case you ask yourself why this is necessary in the context of Wildcard: it's basically for large scale applications that need to decouple the development of several frontends from the backend development. For most users, Wildcard alone is enough.
A preview:
Resolvers + Wildcard integration
With "object-level permissions":
The text was updated successfully, but these errors were encountered: