Skip to content

WIP: Locked Pre defined Schemas / auto migration #6379

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

Closed
wants to merge 1 commit into from

Conversation

Moumouls
Copy link
Member

With the recent add of GraphQL, schema less behavior of Parse could be a problem to use the GraphQL API correctly (due to the auto generation based on existing schemas). So from my own experience with a script that i use on my parse servers, i suggest to add an option schemas to Parse Server that allow to:

  • Define Schema (Rest Interface Like)
  • Auto management feature for fields, indexes, CLPS at start time
  • Lock schema operations on public api to avoid unwanted results in case of parse server restart/deployment

Note: Missing tests, it's just a first architectural push

Tell me what you think about this ?

@Moumouls Moumouls added enhancement type:feature New feature or improvement of existing feature labels Jan 30, 2020
@davimacedo
Copy link
Member

Awesome! Could you please add an example on how to use it?

@Moumouls
Copy link
Member Author

@davimacedo

Here an example of what i want to achieve:

Assuming a Address.ts

export const Address = {
	className: 'Address',
	fields: {
		objectId: { type: 'String' },
		createdAt: {
			type: 'Date',
		},
		updatedAt: {
			type: 'Date',
		},
		ACL: { type: 'ACL' },
		name: { type: 'String', required: true },
		line1: { type: 'String', required: true },
		line2: { type: 'String' },
		city: { type: 'String', required: true },
		zip: { type: 'String', required: true },
		country: { type: 'String', required: true },
		firstname: { type: 'String', required: true },
		lastname: { type: 'String', required: true },
		companyName: { type: 'String' },
		isDefault: { type: 'Boolean' },
		additionalInformations: { type: 'String' },
		user: { type: 'Pointer', targetClass: '_User', required: true },
	},
	indexes: {
		objectId: { objectId: 1 },
		address: { country: 1, line1: 1 },
	},
	classLevelPermissions: {
		find: { requiresAuthentication: true },
		get: { requiresAuthentication: true },
		update: { requiresAuthentication: true },
		create: { requiresAuthentication: true },
		delete: { requiresAuthentication: true },
		readUserFields: ['user'],
		writeUserFields: ['user'],
		addField: {},
	},
}

And here a Parse Server instance.

import { Address } from './Address';
const server = ParseServer.start({
    databaseURI: process.env.MONGO_URL,
    appId: process.env.APP_ID,
    masterKey: process.env.MASTER_KEY,
    serverURL,
    schemas: [Address],
    port: Number(process.env.PORT),
})

@davimacedo
Copy link
Member

It is a good I idea. I'm not sure about having it in the start. Maybe we should first provide a way to pull and push the schema. Wouldn't it be better/easier just use a .json in the same format it is already stored in Parse? @acinader @dplewis thoughts?

@acinader
Copy link
Contributor

acinader commented Feb 12, 2020

I like where this is going.

I did something like this for a project.

  1. I like that it does it at startup, seems like making sure the schema is correct is a good startup activity, should also have a means to update while the server is running?
  2. I used json. I was able to just dump and restore the schema table iirc.

const cloudSchemas = await this.getAllClasses({ clearCache: true });
// We do not check classes to delete, developer need to delete manually classes
// to avoid data loss during auto migration
await Promise.all(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should return this and lose the async.

i.e. return Promise.all(...

if (req.config.schemas) {
throw new Parse.Error(
Parse.Error.OPERATION_FORBIDDEN,
'This server use schemas option, schemas creation/modification operations are blocked. You can still delete a class.'
Copy link
Contributor

@acinader acinader Mar 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This server uses 'Schema Option'. Schema creation/modification operations are blocked. Classes can still be deleted. See: XYZ doc.


Object.keys(cloudSchema.fields)
.filter(fieldName => isNotDefaultField(fieldName))
.map(async fieldName => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assuming accidental use of map and async > .forEach()


Object.keys(cloudSchema.indexes)
.filter(indexName => isNotDefaultIndex(indexName))
.map(async indexName => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous comment on async

@Moumouls
Copy link
Member Author

For Developers that wants this feature asap, here a script that i use on many project to achieve this feature: https://gist.github.com/Moumouls/e4f0c6470398efc7a6a74567982185fa

@mtrezza mtrezza removed 🧬 enhancement type:feature New feature or improvement of existing feature labels Dec 3, 2020
@Moumouls
Copy link
Member Author

Moumouls commented Dec 12, 2020

I'm closing this one since i need a fresh re start with the gist script linked above 😄
Parse community discussion: https://community.parseplatform.org/t/possibility-to-set-class-level-permissions-via-file/1061/20

New issue: #7063

@Moumouls Moumouls closed this Dec 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants