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.