# Kanject.Forms

A dynamic form-builder backend — define schemas in code (annotations, a `FormDefinition`, or the KForm DSL), render them to HTML or JSON, and collect validated submissions into DynamoDB or S3.

> **Private beta:** Kanject.Forms isn't generally available yet — there's no public package or `kanject baas deploy forms` for it. [Request beta access](https://www.kanject.com/baas/forms/) to get early access and help shape the API before GA.

## What it does

- **Schema as code** — define forms with `[Form]` / `[FormField]` / `[FormOption]` annotations, a declarative `FormDefinition`, or the KForm DSL.
- **Field types & options** — short text, email, single/multi-select, file, and more via `FieldType`.
- **Validation** — required, length, range, and regex validators, plus custom `IFormValidator`s.
- **Rendering** — turn a form into HTML or JSON with the Html / Json renderers.
- **Pluggable storage** — persist definitions and submissions to DynamoDB or S3.

## Preview API

*Preview — the module is in private beta; the API may change before GA.* Define a form code-first:

```csharp
using Kanject.Forms.Annotations;

// Define a form as a partial class — code-first, source-generated.
[Form("onboarding", title: "Team onboarding")]
public partial class OnboardingForm
{
    [FormField(FieldType.ShortText, "Full name", Required = true, Order = 1)]
    public partial string FullName { get; set; }

    [FormField(FieldType.Email, "Work email", Required = true, Order = 2)]
    public partial string Email { get; set; }

    [FormField(FieldType.SingleSelect, "Role", Required = true, Order = 3)]
    [FormOption("Admin")]
    [FormOption("Member")]
    public partial string Role { get; set; }
}
```

Register the manager and a store, then create and submit through `IForm` at runtime:

```csharp
// Register the manager (+ a store and validators), then create and submit.
builder.Services
    .AddKanjectFormManager()
    .AddDynamoDbKanjectFormStore(/* store options */)
    .AddStandardKanjectFormValidators();

// IForm is the runtime surface.
public class IntakeService(IForm forms)
{
    public Task<SubmitFormResponse?> SubmitAsync(SubmitFormRequest request, string formId, Guid userId)
        => forms.SubmitFormAsync(request, formId, userId);
}
```

## Related modules

- **[FileServer](https://www.kanject.com/docs/baas-fileserver/)** — Stores form attachments.
- **[Insights](https://www.kanject.com/docs/baas-insights/)** — Analyze submissions.
- **[EventHub](https://www.kanject.com/docs/baas-eventhub/)** — Submission events.

---
_Source: https://www.kanject.com/docs/baas-forms/ · Kanject Docs_
