How to implement original validation in API by using custom function

This tutorial explains how to implement original validation in API using custom functions and API Pre-processing.
This feature allows you to add advanced input validation that cannot be achieved using the standard features alone.

This time, we will implement a validation process that returns an error if the POST email address does not match a specific domain.

Preparation

Create API endpoint

Before starting, let's prepare an API endpoint to implement the validation referring to Configuring endpoints.
This time, we created the following endpoint under "Default".

itemvalue
Pathoriginal_api/sample1
enabled/disabledenabled
ModelCategoryNotification
ModelMagazine
Operationsubscribe

Image from Gyazo

Create custom function

Let's prepare a custom function to write the validation process.

1. Access the Custom function list page

Click [Operation] -> [Custom function] on the side menu. Image from Gyazo

2. Access the Custom function editor page

Click [Add] button on the top right of the Custom function list page.  
Image from Gyazo

3. Enter the title and category

Enter the title, category, and Identifier of the custom function, like below for example:

  • Title:/rcms-api/1/original_api/sample1
  • Category:API
  • Identifier:sample1_function

Note: you cannot duplicate custom functions title in the same category. Please enter a title that isn't identical to others, such as the endpoint name in which the costom function will be implemented.

Image from Gyazo

4. Save the custom function

Click [Add] button on the bottom of the page and save the custom function.

Image from Gyazo

Write the code for the validation process

Next, let's write the code of the validation process.

1. Access the Custom functions list page

Click [Operation] -> [Custom function] on the side menu.
Image from Gyazo

Click the title of the custom function which you have just created.
Image from Gyazo

Input the validation process in the Custom function editor page following the procedure below. Image from Gyazo

2. Initialize the errors variable

Initialize the $errors variable to save the validation result.

Variable nametypedescription
$errorsarraystring array

Enter the following code into the editor.

{* $errors = [] *}
{assign_array var="errors" values=""}

Image from Gyazo

3. Implement the validation

It checks the user's input value and assigns the result to the errors variable.
To refer to the input value, use one of the following variables.

variabledescription
$smarty.getquery parameter
$smarty.postJSON body
$smarty.requestquery parameter & JSON body
{assign_array var="errors" values=""}

{*e.g. returning an error if the POSTed email address does not match a particular domain.*}
{if $smarty.post.email|strpos:'@example.com' === false}
  {* $errors = ["E-mail address is invalid."] *}
  {assign var="errors." value="E-mail address is invalid."}
{/if}

Image from Gyazo

4. Save

After completing the code above, click [Update] to save the configuration. Image from Gyazo

Associate the function to the API

Next, we'll associate the function created to the API.

1. Access the API list page

Click [API] -> [Default] on the side menu.
Image from Gyazo

2. Select the endpoint

Select the endpoint original_api/sample1 you created earlier and click [Pre-processing].
Image from Gyazo

The input fields "Category" and "List" are displayed under the table. Image from Gyazo

3. Associate the function

Select the category and title of the function you created.

  • Category:API
  • List:/rcms-api/1/original_api/sample1

Image from Gyazo

Check the operation of API

Let's send a request from the Swagger UI page and check the operation of the validation process.

1. Access the Swagger UI page

Click [Swagger UI] button on the API list page and access the Swagger UI page.
Image from Gyazo

2. Select the endpoint

Select the endpoint original_api/sample1 and click [Try it out] button. Image from Gyazo

3. Enter the value for which an error will be output

Enter 1 in the magazine_id, and to check the validation process, enter the following value that will trigger an error in [Request body].

Request body
{
  "email": "test@test.com"
}

Click [Execute] button to execute the request. Image from Gyazo

4. Check the response

Check the API response and confirm that the expected error is output.
Image from Gyazo

response
{
  "errors": [
    {
      "code": "unprocessable_entity",
      "message": "E-mail address is invalid."
    }
  ],
  "x-rcms-request-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxx"
}

The association of the function and API is now complete.

Ref: Where to check when the validation error doesn't occur as expected.

If the input validation is not working as expected, check the following points:

  • Whether the function is properly associated with API pre-processing
  • Whether the associated function is correct
  • Whether the variable name (errors) is correct
  • Whether items to be validated are correct
  • Whether the validation logic is correct

Ref: Code example

Here are some examples which you can use for the function

Check if it includes the specific string

{if $smarty.post.column_name|strpos:"EXPECTED STRING" === false}
  {assign var="errors." value="column_name is invalid."}
{/if}

Check if it is a number

{if !$smarty.get.parameter_name|is_numeric}
  {assign var="errors." value="Input number for the parameter_name."}
{/if}

Check the input value which depends on another input

{*
    [e.g.] ext_col_02 is required only when there is a value "1" in ext_col_01.
    ext_col_01: Option item('', '1', '2')
    ext_col_02: Text item
*}
{if $smarty.post.ext_col_01 === '1' || (
  !$smarty.post.ext_col_01|@empty &&
  $smarty.post.ext_col_01.key === '1'
)}
  {if !isset($smarty.post.ext_col_02) || $smarty.post.ext_col_02 === ''}
    {assign var="errors." value="The text item is required."}
  {/if}
{/if}

Apply input validation only to members belonging to a specific group

{if $smarty.session.arrGroup_id|@is_array &&
  101|in_array:$smarty.session.arrGroup_id}
  {if !isset($smarty.post.column_name)}
    {assign var="errors." value="column_name is required."}
  {/if}
{/if}

If you have any other questions, please use our contact form or Slack workspace.