question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Virtual resolver properties

See original GitHub issue

The problem

Currently, there is no differentiation between resolver properties that come from the database and “computed” properties like a fullName which is composed from user.firstName and user.lastName. Consider the following resolver:

type User = {
  firstName: string
  lastName: string
  fullName: string
}

const userResolver = resolve<User, Context>({
  properties: {
    fullName: async (_value, user, context) => {
      return `${user.firstName} ${user.lastName}`
    }
  }
})

Currently we don’t know if this property is completely computed or already exists in the database. Some of the repercussions in a Feathers app is that we can’t use the $select query syntax for resolvers because we don’t know what fields are in the database and which are dynamically resolved so a $select: [ 'fullName', 'firstName' ] would pass fullName as a field to select from to the database and causes an error. Additionally we don’t know that the fullName resolver requires a firstName and lastName to be present on the original data.

Suggestion

Create computed property resolver wrapper that indicates a computed property and optionally pass the names of the dependent fields (a fairly common pattern already in web development, e.g. in React hook effects). This could also address an additional concern brought up by @DaddyWarbucks that the value (the first argument) for a computed resolver will always be undefined. For the above example this would look like this:

import { resolve, computed } from '@feathersjs/schema'

type User = {
  firstName: string
  lastName: string
  fullName: string
}

const userResolver = resolve<User, Context>({
  properties: {
    fullName: computed<User, Context>(async (user, context) => {
      return `${user.firstName} ${user.lastName}`
    }, ['firstName', 'lastName'])
  }
})

It is a little more verbose but would allow tools using the resolver (like schemaHooks.resolveResult) to create a $select that is database friendly and also making sure that all dependent properties are selected.

Related to

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
dafflcommented, Oct 21, 2022

Yeah I didn’t think computed was a great name either. My other thought was virtual. Looking at your snippets I’m actually wondering if this could address the other thing you were mentioning in executing dependent resolver properties as well 🤔

import _ from 'lodash'
import { resolve, computed } from '@feathersjs/schema'

type User = {
  firstName: string
  lastName: string
  fullName: string
  userName: string
}

const userResolver = resolve<User, Context>({
  properties: {
    userName: computed<User, Context>(async (user, context) => {
      return _.camelCase(user.fullName)
    }, ['fullName']),
    fullName: computed<User, Context>(async (user, context) => {
      return `${user.firstName} ${user.lastName}`
    }, ['firstName', 'lastName'])
  }
})
0reactions
dafflcommented, Dec 19, 2022

I’m going to close this since virtual property resolvers are now available. We can create a follow-up issue on how to handle dependencies.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Resolve Promise in mongoose virtual property? - Stack Overflow
I'm using asynchronous virtual properties to count how often that document has been referenced in a specific other collection.
Read more >
Azure DNS Private Resolver endpoints and rulesets
In this article, you'll learn about components of the Azure DNS Private Resolver. Inbound endpoints, outbound endpoints, and DNS forwarding ...
Read more >
Resolvers | feathers
Virtual resolvers are property resolvers that do not use the value but instead always return a value of their own.
Read more >
Resolver - Parcel
Resolver plugins are responsible for turning a dependency specifier into a full file ... This allows programmatically generating virtual modules on demand.
Read more >
DNS attributes for your VPC - Amazon Virtual Private Cloud
The Amazon Route 53 Resolver can resolve private DNS hostnames to private IPv4 addresses for all address spaces, including where the IPv4 address...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found