Forms
A part of the ShipEngine Connect platform is allowing integrations to define
their own forms used for things like registering or connecting a new account.
These forms are defined using the react-jsonschema-form syntax, and are comprised of two parts, a JsonSchema
and a UiSchema
.
Example
Pro Tip
By adding the "ui:order"
property to your UiSchema
you can gaurantee the order that the form fields will be generated in. Due to serialization / deserialization we cannot gaurantee order of form fields without this property.
const JsonSchema = {
type: "object",
title: "Login Form Example",
required: ["email", "password"],
properties: {
email: {
type: "string",
title: "Email Address",
format: "email",
},
password: {
type: "string",
title: "Password",
minLength: 8,
},
},
description: "Connect to your account.",
};
const UiSchema = {
"ui:order": ["email", "password"],
email: {
"ui:autofocus": true,
"ui:emptyValue": "you@example.com",
},
password: {
"ui:help": "Note: password is case sensitive",
"ui:widget": "password",
},
};
export const RegistrationFormSchema = {
JsonSchema,
UiSchema,
};
import {
Carrier
...
} from "@shipengine/connect-carrier-api";
import { RegistrationFormSchema } from "./registration-form";
import { SettingsFormSchema } from "./settings-form";
export const DemoCarrier: Carrier = {
...
AccountModals: {
RegistrationFormSchema,
SettingsFormSchema
},
};
Learning More
You can learn more by visiting the official react-jsonschema-form
website, or by playing with their interactive playground.
Handling input in the Register
method
If you are building a Carrier
app, you must implement a Register
method to
process the user input when a connection is created. Other types of apps do
not currently support the Register
method, however, all of the user input
from the registration form is included in the auth
part of the input in
every function call to your app.
Given the following definition for the JsonSchema
{
"type": "object",
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"CaseSensitive": {
"type": "boolean"
}
}
}
When the "Connect" button is clicked by a user the Register Method would receive a payload looking something like this:
{
"registration_info": {
"email": "test@example.com",
"password": "password",
"CaseSensitive": true
},
"transaction_id": "fa4525b2-8dd2-4514-acf5-5c92173d31fd",
"metadata": {
}
}
...
interface RegistrationForm {
email?: string;
password?: string;
CaseSensitive?: boolean;
}
export const Register = async (request: RegisterRequest): Promise<RegisterResponse> => {
const {
email,
password,
CaseSensitive
} = request.registration_info as RegistrationForm;
...
}
Notice
Notice how the interface for the RegistrationForm
in the typescript code
defined every field as being potentially null given the ?
. This is because we
did not mark any of these fields as required in our JsonSchema.