How to implement original validation in API by using function

This tutorial explains how to implement original validation in API using 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.

Create function

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

1. Access the function list page
Click [Operation] -> [Function] on the side menu.
Image (fetched from Gyazo)

2. Access the function edit page
Click [Add Function] button on the top right of the function list page.  
Image (fetched from Gyazo)

3. Enter the title and category
Enter the title and category of the function, like below for example:

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

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

Image (fetched from Gyazo)

4. Save the function
Click [Add] button on the bottom of the page and save the function.
Image (fetched from Gyazo)

Write the code for the validation process

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

1. Access the functions list page
Click [Operation] -> [Function] on the side menu.
Image (fetched from Gyazo)

Click the title of the function which you have just created.
Image (fetched from Gyazo)

Input the validation process in the function edit page following the procedure below. Image (fetched 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 (fetched 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 (fetched from Gyazo)

4. Save
After completing the code above, click [Update] to save the configuration.
Image (fetched 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] and select the API in which there is an endpoint to update on the side menu.
Image (fetched from Gyazo)

2. Select the endpoint
Select the endpoint to which you want to add the validation and click [Pre-processing].
Image (fetched from Gyazo)

The input fields "Category" and "Contents" are displayed under the table. Image (fetched from Gyazo)

3. Associate the function
Select the category and title of the function you created.

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

Image (fetched 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 (fetched from Gyazo)

2. Select the endpoint
Select the endpoint in which the validation is implemented and click [Try it out] button. Image (fetched from Gyazo)

3. Enter the value for which an error will be output
To check the validation process, enter the value that will trigger an error in [Parameters] or [Request body]. In this case, enter the following in [Request body].

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

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

4. Check the response
Check the API response and confirm that the expected error is output.
Image (fetched 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}