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, and updating settings in the case of shipping integrations. These forms are defined using a library call rect-jsonschema-form 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.

form
registration-form.tscarrier.ts
Copy
Copied
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,
};
Copy
Copied
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.

Registration Form

Given the following definition for the JsonSchema

Copy
Copied
{
  "type": "object",
  "properties": {
    "email": {
      "type": "string"
    },
    "password": {
      "type": "string"
    },
    "CaseSensitive": {
      "type": "boolean"
    }
  }
}

When the button to connect is clicked by a user the Register Method would recieve a payload looking something like this.

Request Payloadregister.ts
Copy
Copied
{
    "registration_info": {
        "email": "test@gmail.com",
        "password": "password",
        "CaseSensitive": true
    },
    "transaction_id": "fa4525b2-8dd2-4514-acf5-5c92173d31fd",
    "metadata": {
    }
}
Copy
Copied
...
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 feild as being potentially null given the ?. This is because we did not mark any of these fields as required in our JsonSchema.