Skip to content

Extensions

Simfinity reads standard GraphQL extensions metadata when building models, input types, and resolvers. Define field extensions on individual field configurations and type extensions on GraphQLObjectType.

Field extensions

ExtensionValueEffect
relationRelationship configurationDeclares how an object or object collection is stored and resolved.
readOnlyBooleanOmits the field from generated create and update inputs.
uniqueBooleanAdds a Mongoose unique index for supported string/enum and numeric fields.
validationsOperation-keyed validatorsRuns field validation during materialization.
stateMachineBoolean, generatedMarks a state field managed by a connected state machine.

relation

javascript
const field = {
  type: CountryType,
  extensions: {
    relation: {
      embedded: false,
      connectionField: 'country',
      displayField: 'name',
    },
  },
};
PropertyDescription
embeddedtrue stores the object inline; false uses referenced records.
connectionFieldFor a reference, the stored ObjectId field; for a reverse collection, the child field linking back to the parent.
displayFieldDescriptive field name exposed through introspection for client tooling.

Set connectionField explicitly on non-embedded relationships. Read-side model generation and resolvers have field-name fallbacks, but write materialization accesses connectionField directly. Explicit configuration keeps reads and writes aligned.

Scalar lists do not need relationship metadata. Object fields and object lists do. Embedded self-references are rejected by model generation. See relationships for complete forward and reverse examples.

readOnly

javascript
createdBy: {
  type: GraphQLString,
  extensions: { readOnly: true },
}

The field remains in the output type and generated model. Assign it in a controller when it is server-owned. readOnly is an input-generation setting, not output authorization or a database-level immutability constraint.

unique

javascript
slug: {
  type: GraphQLString,
  extensions: { unique: true },
}

Uniqueness is enforced by a MongoDB index when that index exists. It is not a pre-save validator. The generator applies this flag to string, enum, and numeric mappings; it does not apply it uniformly to every field kind. Manage index creation and existing duplicates through your application's database process.

validations

javascript
title: {
  type: new GraphQLNonNull(GraphQLString),
  extensions: {
    validations: simfinity.validators.stringLength('Title', 2, 120),
  },
}

The field-level shape is { CREATE: [validator], UPDATE: [validator] }. Each validator exposes validate(typeName, fieldName, value, session). Async validators are awaited. See validation for helpers and custom rules.

Type extensions

ExtensionValueEffect
validations{ CREATE, UPDATE } validator arraysValidates the full input and materialized model after field validation.
scope{ find, get_by_id, aggregate } callbacksAdds filters to generated root reads.

Type validators receive (typeName, args, modelArgs, session). Scope callbacks receive { type, args, operation, context } and mutate args in place. See query scope for supported operations and their authorization boundaries.

Introspection metadata

Simfinity extends GraphQL's __Field introspection type with extensions. Clients can inspect readOnly, stateMachine, and relation metadata:

graphql
query SerieMetadata {
  __type(name: "Serie") {
    fields {
      name
      extensions {
        readOnly
        stateMachine
        relation {
          embedded
          connectionField
          displayField
        }
      }
    }
  }
}

This is a Simfinity introspection extension, not a field in standard GraphQL introspection. It does not expose arbitrary extensions such as validator functions. Avoid schema-cloning middleware; use Envelop plugins and in-place resolver wrapping.

Open source. Released under the Apache 2.0 License.