Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better handling of API-only vs DB-only vs both fields in schemas #2573

Open
SachaG opened this issue May 14, 2020 · 10 comments
Open

Better handling of API-only vs DB-only vs both fields in schemas #2573

SachaG opened this issue May 14, 2020 · 10 comments
Labels

Comments

@SachaG
Copy link
Contributor

SachaG commented May 14, 2020

In Vulcan, any field can be included in:

  • the database
  • the API
  • both

But currently, that distinction is not very clear, and in fact it's not even possible to declare a field to be made available through the API but not insertable in the database at all.

It's all a bit messy, so here is a proposal for a better system.

  1. We keep the existing schema object passed to createCollection for any field that should be included in the database. We keep the current canRead-based permission check to know whether those fields should also be made available through the API.
  2. We support a new apiSchema object that contains fields that should only exist in the API, and not the database.

There are two advantages to this approach:

  1. We are able to distinguish between the two kinds of fields.
  2. We can simplify the syntax for API-only fields:

Before:

const schema = {
  pagePath: {
    type: String,
    optional: true,
    canRead: ["guests"],
    resolveAs: {
      typeName: "String",
      resolver: (post, args, context) => {
        return getPostPageLink(post, false);
      },
  }
}

After:

const apiSchema = {
  pagePath: {
    typeName: "String",
    resolver: () => {...},
  },
}
@SachaG SachaG added the schemas label May 14, 2020
@SachaG
Copy link
Contributor Author

SachaG commented May 14, 2020

This would also make it easier to get rid of resolveAs, which while very handy introduces an extra concept that wouldn't be needed if there was an easier way to define API-only fields.

@SachaG
Copy link
Contributor Author

SachaG commented May 14, 2020

@SachaG
Copy link
Contributor Author

SachaG commented May 14, 2020

This also means moving relation out of resolveAs, which probably makes sense anyway.

@Neobii
Copy link
Contributor

Neobii commented May 14, 2020

I think you should also do something with the hidden property. I think this gets a little confusing between specifying fields on smart form and having view related things on the schema.

@SachaG
Copy link
Contributor Author

SachaG commented May 14, 2020

Here's a diagram:

Frame 1

@SachaG
Copy link
Contributor Author

SachaG commented May 14, 2020

An added benefit is that API schemas only need to be defined on the server, which lightens the client bundle a tiny bit.

Also a common problem with these fields is that you need to do API calls or run other async, server-only code. There wasn't an elegant way to do this previously, you add to extend specific fields on the server but the syntax was clunky.

@Neobii
Copy link
Contributor

Neobii commented May 15, 2020

I like the idea of tightly coupling Vulcan to mongodB, however I think while working in this area, we can get some of the naming conventions to revolve more around GraphQL types than MongoDB collections.

@SachaG
Copy link
Contributor Author

SachaG commented May 18, 2020

Frame 1

We could even have a separate database schema to mirror the API schema and hold fields that exist in the database but not in the API, since those fields also don't need to be exposed to the client. This is also an elegant way of improving security, since you'd know there'd be no chance of a dbSchema field being exposed through the API by mistake.

As far as naming goes, I guess we could start calling the "collection schema" the "main" schema or "common" schema maybe?

@Neobii
Copy link
Contributor

Neobii commented May 18, 2020

One thing though as far as the syntax to consider is what will it look like using typescript interfaces. Implementing interfaces would help with code hinting on how your data is structured without having to reference the schema.

@SachaG
Copy link
Contributor Author

SachaG commented May 19, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants