github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/docs/guide/basics/validation.html (about)

     1  <!DOCTYPE html>
     2  <html lang="en-US">
     3    <head>
     4      <meta charset="utf-8">
     5      <meta name="viewport" content="width=device-width,initial-scale=1">
     6      <title>Validation | Goyave</title>
     7      <meta name="generator" content="VuePress 1.5.3">
     8      <link rel="icon" type="image/png" sizes="16x16" href="/goyave/goyave_16.png">
     9      <link rel="icon" type="image/png" sizes="32x32" href="/goyave/goyave_32.png">
    10      <link rel="icon" type="image/png" sizes="64x64" href="/goyave/goyave_64.png">
    11      <link rel="icon" type="image/png" sizes="128x128" href="/goyave/goyave_128.png">
    12      <link rel="icon" type="image/png" sizes="256x256" href="/goyave/goyave_256.png">
    13      <link rel="icon" type="image/png" sizes="512x512" href="/goyave/goyave_512.png">
    14      <meta name="description" content="Goyave is a Golang web API framework aiming at cleanliness, fast development and power.">
    15      <meta name="og:title" content="Validation - Goyave">
    16      <meta name="twitter:title" content="Validation - Goyave">
    17      <meta name="title" content="Validation - Goyave">
    18      <meta property="twitter:description" content="Goyave is a Golang web API framework aiming at cleanliness, fast development and power.">
    19      <meta property="twitter:image:src" content="https://system-glitch.github.io/goyave/goyave_banner.png">
    20      <meta property="twitter:card" content="summary_large_image">
    21      <meta property="og:type" content="website">
    22      <meta property="og:description" content="Goyave is a Golang web API framework aiming at cleanliness, fast development and power.">
    23      <meta property="og:image" content="https://system-glitch.github.io/goyave/goyave_banner.png">
    24      <meta property="og:site_name" content="Goyave">
    25      <link rel="preload" href="/goyave/assets/css/0.styles.589fd562.css" as="style"><link rel="preload" href="/goyave/assets/js/app.092490a7.js" as="script"><link rel="preload" href="/goyave/assets/js/4.75a9cc68.js" as="script"><link rel="preload" href="/goyave/assets/js/1.121dd9ed.js" as="script"><link rel="preload" href="/goyave/assets/js/23.931b2034.js" as="script"><link rel="preload" href="/goyave/assets/js/5.c83f1192.js" as="script"><link rel="prefetch" href="/goyave/assets/js/10.2f07bbf5.js"><link rel="prefetch" href="/goyave/assets/js/11.2d66fdef.js"><link rel="prefetch" href="/goyave/assets/js/12.63171b15.js"><link rel="prefetch" href="/goyave/assets/js/13.770050f3.js"><link rel="prefetch" href="/goyave/assets/js/14.b933d8cf.js"><link rel="prefetch" href="/goyave/assets/js/15.36df2a66.js"><link rel="prefetch" href="/goyave/assets/js/16.ed66719e.js"><link rel="prefetch" href="/goyave/assets/js/17.7bef5f05.js"><link rel="prefetch" href="/goyave/assets/js/18.470b55ed.js"><link rel="prefetch" href="/goyave/assets/js/19.90e0dab8.js"><link rel="prefetch" href="/goyave/assets/js/20.3a300ca3.js"><link rel="prefetch" href="/goyave/assets/js/21.c3fd6053.js"><link rel="prefetch" href="/goyave/assets/js/22.d5569617.js"><link rel="prefetch" href="/goyave/assets/js/24.1a4755e7.js"><link rel="prefetch" href="/goyave/assets/js/25.0d463913.js"><link rel="prefetch" href="/goyave/assets/js/26.3c173a7a.js"><link rel="prefetch" href="/goyave/assets/js/27.9c5b36f2.js"><link rel="prefetch" href="/goyave/assets/js/28.41e055b7.js"><link rel="prefetch" href="/goyave/assets/js/29.b87adf4a.js"><link rel="prefetch" href="/goyave/assets/js/3.ef71e77d.js"><link rel="prefetch" href="/goyave/assets/js/6.2336bf0c.js"><link rel="prefetch" href="/goyave/assets/js/7.d60e55c1.js"><link rel="prefetch" href="/goyave/assets/js/8.2ee33a42.js"><link rel="prefetch" href="/goyave/assets/js/9.8e043d60.js">
    26      <link rel="stylesheet" href="/goyave/assets/css/0.styles.589fd562.css">
    27    </head>
    28    <body>
    29      <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/goyave/" class="home-link router-link-active"><img src="/goyave/goyave_64.png" alt="Goyave" class="logo"> <span class="site-name can-hide">Goyave</span></a> <div class="links"><div class="user-settings"><a title="Dark theme" href="#" class="settings-button"><svg aria-hidden="true" data-prefix="fas" data-icon="cog" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="svg-inline--fa fa-cog fa-w-16 settings-icon"><path fill="currentColor" d="M8 0c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zM8 15c-3.9 0-7-3.1-7-7 0-2.4 1.2-4.6 3.2-5.9-0.1 0.6-0.2 1.3-0.2 1.9 0 4.9 4 8.9 8.9 9-1.3 1.3-3 2-4.9 2z"></path></svg></a></div> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/goyave/guide/" class="nav-link router-link-active">
    30    Guide
    31  </a></div><div class="nav-item"><a href="https://pkg.go.dev/github.com/System-Glitch/goyave/v2" target="_blank" rel="noopener noreferrer" class="nav-link external">
    32    pkg.go.dev
    33    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <a href="https://github.com/System-Glitch/goyave" target="_blank" rel="noopener noreferrer" class="repo-link">
    34      GitHub
    35      <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/goyave/guide/" class="nav-link router-link-active">
    36    Guide
    37  </a></div><div class="nav-item"><a href="https://pkg.go.dev/github.com/System-Glitch/goyave/v2" target="_blank" rel="noopener noreferrer" class="nav-link external">
    38    pkg.go.dev
    39    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <a href="https://github.com/System-Glitch/goyave" target="_blank" rel="noopener noreferrer" class="repo-link">
    40      GitHub
    41      <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Guide</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>The Basics</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/goyave/guide/basics/routing.html" class="sidebar-link">Routing</a></li><li><a href="/goyave/guide/basics/middleware.html" class="sidebar-link">Middleware</a></li><li><a href="/goyave/guide/basics/requests.html" class="sidebar-link">Requests</a></li><li><a href="/goyave/guide/basics/controllers.html" class="sidebar-link">Controllers</a></li><li><a href="/goyave/guide/basics/responses.html" class="sidebar-link">Responses</a></li><li><a href="/goyave/guide/basics/database.html" class="sidebar-link">Database</a></li><li><a href="/goyave/guide/basics/validation.html" aria-current="page" class="active sidebar-link">Validation</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#introduction" class="sidebar-link">Introduction</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#rules-sets" class="sidebar-link">Rules sets</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#available-validation-rules" class="sidebar-link">Available validation rules</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#custom-rules" class="sidebar-link">Custom rules</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#validating-arrays" class="sidebar-link">Validating arrays</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#placeholders" class="sidebar-link">Placeholders</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#manual-validation" class="sidebar-link">Manual validation</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/basics/validation.html#alternative-syntax" class="sidebar-link">Alternative syntax</a></li></ul></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Advanced</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="validation"><a href="#validation" class="header-anchor">#</a> Validation</h1> <p></p><div class="table-of-contents"><ul><li><a href="#introduction">Introduction</a></li><li><a href="#rules-sets">Rules sets</a></li><li><a href="#available-validation-rules">Available validation rules</a></li><li><a href="#custom-rules">Custom rules</a><ul><li><a href="#adding-a-message-to-your-rule">Adding a message to your rule</a></li></ul></li><li><a href="#validating-arrays">Validating arrays</a><ul><li><a href="#n-dimensional-arrays">N-dimensional arrays</a></li></ul></li><li><a href="#placeholders">Placeholders</a><ul><li><a href="#available-placeholders">Available placeholders</a></li></ul></li><li><a href="#manual-validation">Manual validation</a></li><li><a href="#alternative-syntax">Alternative syntax</a></li></ul></div><p></p> <h2 id="introduction"><a href="#introduction" class="header-anchor">#</a> Introduction</h2> <p>Goyave provides a powerful, yet easy way to validate all incoming data, no matter its type or its format, thanks to a large number of validation rules.</p> <p>Incoming requests are validated using <strong>rules set</strong>, which associate rules with each expected field in the request.</p> <p>Validation rules can <strong>alter the raw data</strong>. That means that when you validate a field to be number, if the validation passes, you are ensured that the data you'll be using in your controller handler is a <code>float64</code>. Or if you're validating an IP, you get a <code>net.IP</code> object.</p> <p>If a request contains a field with a <code>nil</code>/<code>null</code> value, and that this field doesn't have the <code>nullable</code> rule, the field is <strong>removed</strong> entirely from the request.</p> <p>Validation is automatic. You just have to define a rules set and assign it to a route. When the validation doesn't pass, the request is stopped and the validation errors messages are sent as a response, using the correct <a href="/goyave/guide/advanced/localization.html">language</a>. The HTTP response code of failed validation is <strong>422 &quot;Unprocessable Entity&quot;</strong>, or <strong>400 &quot;Bad Request&quot;</strong> if the body could not be parsed.</p> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>You can customize the validation error messages by editing <code>resources/lang/&lt;language&gt;/rules.json</code>. Learn more in the <a href="/goyave/guide/advanced/localization.html">localization</a> section.</p></div> <p>The following features require the <code>validation</code> package to be imported.</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">import</span> <span class="token string">&quot;github.com/System-Glitch/goyave/v2/validation&quot;</span>
    42  </code></pre></div><h2 id="rules-sets"><a href="#rules-sets" class="header-anchor">#</a> Rules sets</h2> <p>Rule sets are defined in the same package as the controller, typically in a separate file named <code>request.go</code>. Rule sets are named after the name of the controller handler they will be used with, and end with <code>Request</code>. For example, a rule set for the <code>Store</code> handler will be named <code>StoreRequest</code>. If a rule set can be used for multiple handlers, consider using a name suited for all of them. The rules for a store operation are often the same for update operations, so instead of duplicating the set, create one unique set called <code>UpsertRequest</code>.</p> <p><strong>Example:</strong> (<code>http/controller/product/request.go</code>)</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">var</span> <span class="token punctuation">(</span>
    43  	StoreRequest validation<span class="token punctuation">.</span>RuleSet <span class="token operator">=</span> validation<span class="token punctuation">.</span>RuleSet<span class="token punctuation">{</span>
    44  		<span class="token string">&quot;name&quot;</span><span class="token punctuation">:</span>  <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;between:3,50&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    45  		<span class="token string">&quot;price&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;numeric&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;min:0.01&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    46  		<span class="token string">&quot;image&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">&quot;nullable&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;file&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;image&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;max:2048&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;count:1&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    47      <span class="token punctuation">}</span>
    48      
    49      <span class="token comment">// ...</span>
    50  <span class="token punctuation">)</span>
    51  </code></pre></div><div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p><strong>The order in which you assign rules is important</strong>, as rules are executed in this order. The rules checking for the type of the data should <strong>always be first</strong>, or after <code>required</code> and <code>nullable</code>.</p> <p>If a field is not <strong>required</strong> and is missing from the request, <strong>no rules are checked</strong>!</p></div> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <p><code>validation.RuleSet</code> is an alias for <code>map[string][]string</code>.</p></div> <hr> <p>Once your rules sets are defined, you need to assign them to your routes using the <code>Validate()</code> method. Learn more about routing in the <a href="/goyave/guide/basics/routing.html">dedicated section</a>.</p> <div class="language-go extra-class"><pre class="language-go"><code>router<span class="token punctuation">.</span><span class="token function">Post</span><span class="token punctuation">(</span><span class="token string">&quot;/product&quot;</span><span class="token punctuation">,</span> product<span class="token punctuation">.</span>Store<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Validate</span><span class="token punctuation">(</span>product<span class="token punctuation">.</span>StoreRequest<span class="token punctuation">)</span>
    52  </code></pre></div><h2 id="available-validation-rules"><a href="#available-validation-rules" class="header-anchor">#</a> Available validation rules</h2> <div class="table"><p><a href="#required">Required</a> <a href="#nullable">Nullable</a> <a href="#numeric">Numeric</a> <a href="#integer">Integer</a> <a href="#min-value">Min</a> <a href="#max-value">Max</a> <a href="#between-min-max">Between</a> <a href="#greater-than-field">Greater than</a> <a href="#greater-than-equal-field">Greater than or equal</a> <a href="#lower-than-field">Lower than</a> <a href="#lower-than-equal-field">Lower than or equal</a> <a href="#string">String</a> <a href="#array-type">Array</a> <a href="#distinct">Distinct</a> <a href="#digits">Digits</a> <a href="#regex-pattern">Regex</a> <a href="#email">Email</a> <a href="#size-value">Size</a> <a href="#alpha">Alpha</a> <a href="#alpha-dash">Alpha dash</a> <a href="#alpha-num">Alpha numeric</a> <a href="#starts-with-value1">Starts with</a> <a href="#ends-with-value1">Ends with</a> <a href="#in-value1-value2">In</a> <a href="#not-in-value1-value2">Not in</a> <a href="#in-array-field">In array</a> <a href="#not-in-array-field">Not in array</a> <a href="#timezone">Timezone</a> <a href="#ip">IP</a> <a href="#ipv4">IPv4</a> <a href="#ipv6">IPv6</a> <a href="#json">JSON</a> <a href="#url">URL</a> <a href="#uuid-version">UUID</a> <a href="#bool">Bool</a> <a href="#same-field">Same</a> <a href="#different-field">Different</a> <a href="#confirmed">Confirmed</a> <a href="#file">File</a> <a href="#mime-foo">MIME</a> <a href="#image">Image</a> <a href="#extension-foo">Extension</a> <a href="#count-value">Count</a> <a href="#count-min-value">Count min</a> <a href="#count-max-value">Count max</a> <a href="#count-between-min-max">Count between</a> <a href="#date-format">Date</a> <a href="#before-date">Before</a> <a href="#before-equal-date">Before or equal</a> <a href="#after-date">After</a> <a href="#after-equal-date">After or equal</a> <a href="#date-equals-date">Date equals</a> <a href="#date-between-date1-date2">Date between</a></p></div><h4 id="required"><a href="#required" class="header-anchor">#</a> required</h4> <p>The field under validation must be present.</p> <p>If the field is a string, the string must not be empty. If a field is <code>null</code> and has the <code>nullable</code> rule, the <code>required</code> rules passes. As non-nullable fields are removed if they have a <code>null</code> value, the <code>required</code> rule doesn't pass if a field is <code>null</code> and doesn't have the <code>nullable</code> rule.</p> <h4 id="nullable"><a href="#nullable" class="header-anchor">#</a> nullable</h4> <p>The field under validation can have a <code>nil</code>/<code>null</code> value. If this rule is missing from the rules set, the field will be <strong>removed</strong> if it is <code>null</code>. This rule is especially useful when working with JSON requests or with primitives that can contain null values.</p> <p>Be sure to check if your field is not null before using it in your handlers.</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token comment">// In this example, field is numeric</span>
    53  <span class="token keyword">if</span> val<span class="token punctuation">,</span> exists <span class="token operator">:=</span> request<span class="token punctuation">.</span>Data<span class="token punctuation">[</span><span class="token string">&quot;field&quot;</span><span class="token punctuation">]</span><span class="token punctuation">;</span> exists <span class="token operator">&amp;&amp;</span> val <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    54      field<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> request<span class="token punctuation">.</span>Data<span class="token punctuation">[</span><span class="token string">&quot;field&quot;</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token builtin">float64</span><span class="token punctuation">)</span>
    55  <span class="token punctuation">}</span>
    56  </code></pre></div><h4 id="numeric"><a href="#numeric" class="header-anchor">#</a> numeric</h4> <p>The field under validation must be numeric. Strings that can be converted to numbers are accepted.
    57  This rule converts the field to <code>float64</code> if it passes.</p> <h4 id="integer"><a href="#integer" class="header-anchor">#</a> integer</h4> <p>The field under validation must be an integer. Strings that can be converted to an integer are accepted.
    58  This rule converts the field to <code>int</code> if it passes.</p> <h4 id="min-value"><a href="#min-value" class="header-anchor">#</a> min:value</h4> <p>Depending on its type, the field under validation must be at least <code>value</code>.
    59  Strings, numerics, array, and files are evaluated using the same method as the <a href="#size-value"><code>size</code></a> rule.</p> <h4 id="max-value"><a href="#max-value" class="header-anchor">#</a> max:value</h4> <p>Depending on its type, the field under validation must not be superior to <code>value</code>.
    60  Strings, numerics, array, and files are evaluated using the same method as the <a href="#size-value"><code>size</code></a> rule.</p> <h4 id="between-min-max"><a href="#between-min-max" class="header-anchor">#</a> between:min,max</h4> <p>Depending on its type, the field under validation must be between <code>min</code> and <code>max</code>.
    61  Strings, numerics, array, and files are evaluated using the same method as the <a href="#size-value"><code>size</code></a> rule.</p> <h4 id="greater-than-field"><a href="#greater-than-field" class="header-anchor">#</a> greater_than:field</h4> <p>The field under validation must be greater than the given <code>field</code>. The two fields must have the same type.
    62  Strings, numerics, array, and files are evaluated using the same method as the <a href="#size-value"><code>size</code></a> rule.</p> <h4 id="greater-than-equal-field"><a href="#greater-than-equal-field" class="header-anchor">#</a> greater_than_equal:field</h4> <p>The field under validation must be greater or equal to the given <code>field</code>. The two fields must have the same type.
    63  Strings, numerics, array, and files are evaluated using the same method as the <a href="#size-value"><code>size</code></a> rule.</p> <h4 id="lower-than-field"><a href="#lower-than-field" class="header-anchor">#</a> lower_than:field</h4> <p>The field under validation must be lower than the given <code>field</code>. The two fields must have the same type.
    64  Strings, numerics, array, and files are evaluated using the same method as the <a href="#size-value"><code>size</code></a> rule.</p> <h4 id="lower-than-equal-field"><a href="#lower-than-equal-field" class="header-anchor">#</a> lower_than_equal:field</h4> <p>The field under validation must be lower or equal to the given <code>field</code>. The two fields must have the same type.
    65  Strings, numerics, array, and files are evaluated using the same method as the <a href="#size-value"><code>size</code></a> rule.</p> <h4 id="string"><a href="#string" class="header-anchor">#</a> string</h4> <p>The field under validation must be a string.</p> <h4 id="array-type"><a href="#array-type" class="header-anchor">#</a> array:type</h4> <p>The field under validation must be an array. The <code>type</code> parameter is <strong>optional</strong>.</p> <p>If no type is provided, the field has the type <code>[]interface{}</code> after validation. If a type is provided, the array is converted to a slice of the correct type, and all values in the array are validated in the same way as standard fields.</p> <p>For example, with the rule <code>array:url</code>, all values must be valid URLs and the field will be converted to <code>[]*url.URL</code>.</p> <p><strong>Available types:</strong></p> <ul><li><code>string</code></li> <li><code>numeric</code></li> <li><code>integer</code></li> <li><code>timezone</code></li> <li><code>ip</code>, <code>ipv4</code>, <code>ipv6</code></li> <li><code>url</code></li> <li><code>uuid</code></li> <li><code>bool</code></li> <li><code>date</code></li></ul> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>For the <code>uuid</code> and <code>date</code> types, you can pass a second parameter: <code>array:date,02-01-2006</code></p></div> <h4 id="distinct"><a href="#distinct" class="header-anchor">#</a> distinct</h4> <p>The field under validation must be an array and have distinct values.</p> <h4 id="digits"><a href="#digits" class="header-anchor">#</a> digits</h4> <p>The field under validation must be a string and contain only digits.</p> <h4 id="regex-pattern"><a href="#regex-pattern" class="header-anchor">#</a> regex:pattern</h4> <p>The field under validation must be a string and match the given <code>pattern</code>.</p> <h4 id="email"><a href="#email" class="header-anchor">#</a> email</h4> <p>The field under validation must be a string and be an email address.</p> <div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p>This rule is not enough to properly validate email addresses. The only way to ensure an email address is valid is by sending a confirmation email.</p></div> <h4 id="size-value"><a href="#size-value" class="header-anchor">#</a> size:value</h4> <p>Depending on its type, the field under validation must:</p> <ul><li>Strings: have a length of <code>value</code> characters.</li> <li>Numerics: be equal to <code>value</code>.</li> <li>Arrays: exactly have <code>value</code> items.</li> <li>Files: weight exactly <code>value</code> KiB.
    66  <ul><li><em>Note: for this rule only (not for <code>min</code>, <code>max</code>, etc), the size of the file under validation is <strong>rounded</strong> to the closest KiB.</em></li> <li>When the field is a multi-files upload, the size of <strong>all files</strong> is checked.</li></ul></li></ul> <div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p>If the value cannot be validated because its type is unsupported, the rule passes. Therefore, you should always validate the type of the field <strong>before</strong> using the <code>size</code>, <code>min</code>, <code>lower_than</code>, ... rules.</p></div> <h4 id="alpha"><a href="#alpha" class="header-anchor">#</a> alpha</h4> <p>The field under validation must be a string and be entirely alphabetic characters.</p> <h4 id="alpha-dash"><a href="#alpha-dash" class="header-anchor">#</a> alpha_dash</h4> <p>The field under validation must be a string and be entirely alphabetic-numeric characters, dashes or underscores.</p> <h4 id="alpha-num"><a href="#alpha-num" class="header-anchor">#</a> alpha_num</h4> <p>The field under validation must be a string and be entirely alphabetic-numeric characters.</p> <h4 id="starts-with-value1"><a href="#starts-with-value1" class="header-anchor">#</a> starts_with:value1,...</h4> <p>The field under validation must be a string and start with of the given values.</p> <h4 id="ends-with-value1"><a href="#ends-with-value1" class="header-anchor">#</a> ends_with:value1,...</h4> <p>The field under validation must be a string and end with one of the given values.</p> <h4 id="in-value1-value2"><a href="#in-value1-value2" class="header-anchor">#</a> in:value1,value2,...</h4> <p>The field under validation must be a one of the given values. Only numerics and strings are checked.</p> <h4 id="not-in-value1-value2"><a href="#not-in-value1-value2" class="header-anchor">#</a> not_in:value1,value2,...</h4> <p>The field under validation must not be a one of the given values. Only numerics and strings are checked.</p> <h4 id="in-array-field"><a href="#in-array-field" class="header-anchor">#</a> in_array:field</h4> <p>The field under validation must be a one of the values in the given <code>field</code>. Only numerics and strings are checked, and the given <code>field</code> must be an array.</p> <h4 id="not-in-array-field"><a href="#not-in-array-field" class="header-anchor">#</a> not_in_array:field</h4> <p>The field under validation must not be a one of the values in the given <code>field</code>. Only numerics and strings are checked, and the given <code>field</code> must be an array.</p> <h4 id="timezone"><a href="#timezone" class="header-anchor">#</a> timezone</h4> <p>The field under validation must be a string and be a valid timezone. This rule converts the field to <code>*time.Location</code> if it passes.</p> <p>Valid timezones are:</p> <ul><li>UTC</li> <li>Timezones from the IANA Time Zone database, such as <code>America/New_York</code></li></ul> <p>The time zone database needed by LoadLocation may not be present on all systems, especially non-Unix systems. The rules looks in the directory or uncompressed zip file
    67  named by the <code>ZONEINFO</code> environment variable, if any, then looks in known installation locations on Unix systems, and finally looks in <code>$GOROOT/lib/time/zoneinfo.zip</code>.</p> <h4 id="ip"><a href="#ip" class="header-anchor">#</a> ip</h4> <p>The field under validation must be a string and be either an IPv4 address or an IPv6 address.
    68  This rule converts the field to <code>net.IP</code> if it passes.</p> <h4 id="ipv4"><a href="#ipv4" class="header-anchor">#</a> ipv4</h4> <p>The field under validation must be a string and be an IPv4 address.
    69  This rule converts the field to <code>net.IP</code> if it passes.</p> <h4 id="ipv6"><a href="#ipv6" class="header-anchor">#</a> ipv6</h4> <p>The field under validation must be a string and be an IPv6 address.
    70  This rule converts the field to <code>net.IP</code> if it passes.</p> <h4 id="json"><a href="#json" class="header-anchor">#</a> json</h4> <p>The field under validation must be a valid JSON string. This rule unmarshals the string and sets the field value to the unmarshalled result.</p> <h4 id="url"><a href="#url" class="header-anchor">#</a> url</h4> <p>The field under validation must be a valid URL.
    71  This rule converts the field to <code>*url.URL</code> if it passes.</p> <h4 id="uuid-version"><a href="#uuid-version" class="header-anchor">#</a> uuid:version</h4> <p>The field under validation must be a string and a valid UUID.</p> <p>The <code>version</code> parameter is <strong>optional</strong>.</p> <ul><li>If a <code>version</code> is given (<code>uuid:3</code>,<code>uuid:4</code>,<code>uuid:5</code>), the rule will pass only if the version of the UUID matches.</li> <li>If no <code>version</code> is given, any UUID version is accepted.</li></ul> <p>This rule converts the field to <code>uuid.UUID</code> if it passes.</p> <h4 id="bool"><a href="#bool" class="header-anchor">#</a> bool</h4> <p>The field under validation must be a boolean or one of the following values:</p> <ul><li><code>1</code>/<code>0</code></li> <li><code>&quot;1&quot;</code>/<code>&quot;0&quot;</code></li> <li><code>&quot;on&quot;</code>/<code>&quot;off&quot;</code></li> <li><code>&quot;true&quot;</code>/<code>&quot;false&quot;</code></li> <li><code>&quot;yes&quot;</code>/<code>&quot;no&quot;</code></li></ul> <p>This rule converts the field to <code>bool</code> if it passes.</p> <h4 id="same-field"><a href="#same-field" class="header-anchor">#</a> same:field</h4> <p>The field under validation must have the same value as the given <code>field</code>. For arrays, the two fields must have the same values in the same order.</p> <p>The two fields must have the same type. Files are not checked.</p> <h4 id="different-field"><a href="#different-field" class="header-anchor">#</a> different:field</h4> <p>The field under validation must have a different value from the given <code>field</code>. For arrays, the two fields must have different values or not be in the same order.</p> <p>The two fields must have the same type. Files are not checked.</p> <h4 id="confirmed"><a href="#confirmed" class="header-anchor">#</a> confirmed</h4> <p>The field under validation must have a matching <code>foo_confirmation</code>. This rule validate equality in the same way as the <a href="#same-field"><code>same</code></a> rule.</p> <p>For example, if the field under validation is <code>password</code>, a matching <code>password_confirmation</code> field must be present in the input.</p> <h4 id="file"><a href="#file" class="header-anchor">#</a> file</h4> <p>The field under validation must be a file. Multi-files are supported.
    72  This rule converts the field to <code>[]filesystem.File</code> if it passes.</p> <h4 id="mime-foo"><a href="#mime-foo" class="header-anchor">#</a> mime:foo,...</h4> <p>The field under validation must be a file and match one of the given MIME types. If the field is a multi-files, all files must satisfy this rule.</p> <h4 id="image"><a href="#image" class="header-anchor">#</a> image</h4> <p>The field under validation must be a file and match one of the following MIME types:</p> <ul><li><code>image/jpeg</code></li> <li><code>image/png</code></li> <li><code>image/gif</code></li> <li><code>image/bmp</code></li> <li><code>image/svg+xml</code></li> <li><code>image/webp</code></li></ul> <p>If the field is a multi-files, all files must satisfy this rule.</p> <h4 id="extension-foo"><a href="#extension-foo" class="header-anchor">#</a> extension:foo,...</h4> <p>The field under validation must be a file and match one of the given extensions. If the field is a multi-files, all files must satisfy this rule.</p> <h4 id="count-value"><a href="#count-value" class="header-anchor">#</a> count:value</h4> <p>The field under validation must be a multi-file and contain <code>value</code> files.</p> <h4 id="count-min-value"><a href="#count-min-value" class="header-anchor">#</a> count_min:value</h4> <p>The field under validation must be a multi-file and contain at least <code>value</code> files.</p> <h4 id="count-max-value"><a href="#count-max-value" class="header-anchor">#</a> count_max:value</h4> <p>The field under validation must be a multi-file and may not contain more than <code>value</code> files.</p> <h4 id="count-between-min-max"><a href="#count-between-min-max" class="header-anchor">#</a> count_between:min,max</h4> <p>The field under validation must be a multi-file and contain between <code>min</code> and <code>max</code> files.</p> <h4 id="date-format"><a href="#date-format" class="header-anchor">#</a> date:format</h4> <p>The field under validation must be a string representing a date. The <code>format</code> is optional. If no format is given, the <code>2006-01-02</code> format is used.</p> <p>This rule converts the field to <code>time.Time</code> if it passes.</p> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>See the <a href="https://golang.org/src/time/format.go" target="_blank" rel="noopener noreferrer">Golang datetime format<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>.</p></div> <div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p>When validating dates by comparing them together, the order of the declaration of the fields in the request is important. For example, if you want to validate that an end date is after a start date, the start date should be declared <strong>before</strong> the end date in the rules set.</p> <p>If a date has not been validated and converted yet, the date comparison rules will attempt to parse the dates using the following format: <code>2006-01-02</code>.</p></div> <h4 id="before-date"><a href="#before-date" class="header-anchor">#</a> before:date</h4> <p>The field under validation must be a value preceding the given date. The <code>date</code> must be written using following format: <code>2006-01-02T15:04:05</code>.</p> <p>If the name of another field is given as a <code>date</code>, then the two fields must be a date and the field under validation must be preceding the given field.</p> <h4 id="before-equal-date"><a href="#before-equal-date" class="header-anchor">#</a> before_equal:date</h4> <p>The field under validation must be a value preceding or equal to the given date. The <code>date</code> must be written using following format: <code>2006-01-02T15:04:05</code>.</p> <p>If the name of another field is given as a <code>date</code>, then the two fields must be a date and the field under validation must be preceding or equal to given field.</p> <h4 id="after-date"><a href="#after-date" class="header-anchor">#</a> after:date</h4> <p>The field under validation must be a value after the given date. The <code>date</code> must be written using following format: <code>2006-01-02T15:04:05</code>.</p> <p>If the name of another field is given as a <code>date</code>, then the two fields must be a date and the field under validation must be preceding the given field.</p> <h4 id="after-equal-date"><a href="#after-equal-date" class="header-anchor">#</a> after_equal:date</h4> <p>The field under validation must be a value after or equal to the given date. The <code>date</code> must be written using following format: <code>2006-01-02T15:04:05</code>.</p> <p>If the name of another field is given as a <code>date</code>, then the two fields must be a date and the field under validation must be after or equal to given field.</p> <h4 id="date-equals-date"><a href="#date-equals-date" class="header-anchor">#</a> date_equals:date</h4> <p>The field under validation must be a value equal to the given date. The <code>date</code> must be written using following format: <code>2006-01-02T15:04:05</code>.</p> <p>If the name of another field is given as a <code>date</code>, then the two fields must be a date and the field under validation must be equal to given field.</p> <h4 id="date-between-date1-date2"><a href="#date-between-date1-date2" class="header-anchor">#</a> date_between:date1,date2</h4> <p>The field under validation must be a value between or equal to the given dates. The given dates must be written using following format: <code>2006-01-02T15:04:05</code>.</p> <p>If the name of another field is given as a date, then all the fields must be a date and the field under validation must be between or equal to given fields.</p> <h2 id="custom-rules"><a href="#custom-rules" class="header-anchor">#</a> Custom rules</h2> <p>If none of the available validation rules satisfy your needs, you can implement custom validation rules. To do so, create a new file <code>http/validation/validation.go</code> in which you are going to define your custom rules.</p> <p>Rules definition shouldn't be exported, and start with <code>validate</code>. A rule returns a <code>bool</code>, indicating if the validation passed or not.</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">validateCustomFormat</span><span class="token punctuation">(</span>field <span class="token builtin">string</span><span class="token punctuation">,</span> value <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> parameters <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">,</span> form <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span>
    73      str<span class="token punctuation">,</span> ok <span class="token operator">:=</span> value<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span>
    74  
    75      <span class="token keyword">if</span> ok <span class="token punctuation">{</span> <span class="token comment">// The data under validation is a string</span>
    76          <span class="token keyword">return</span> regexp<span class="token punctuation">.</span><span class="token function">MustCompile</span><span class="token punctuation">(</span>parameters<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">MatchString</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span>
    77      <span class="token punctuation">}</span>
    78  
    79      <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token comment">// Cannot validate this field</span>
    80  <span class="token punctuation">}</span>
    81  </code></pre></div><div class="custom-block tip"><p class="custom-block-title">TIP</p> <ul><li><code>validation.RuleFunc</code> is an alias for <code>func(string, interface{}, []string, map[string]interface{}) bool</code></li> <li>The <code>form</code> parameter lets you access the whole form data, and modify it if needed.</li> <li>The custom rule in the example above validates a string using a regex. If you need this kind of validation, prefer the included <code>regex</code> validation rule.</li></ul></div> <p>Now that your rule behavior is defined, you need to <strong>register</strong> your rule. Do this in an <code>init()</code> function in your <code>validation.go</code> file.</p> <h4 id="validation-addrule"><a href="#validation-addrule" class="header-anchor">#</a> validation.AddRule</h4> <p>Register a validation rule.</p> <p>The rule will be usable in request validation by using the given rule name.</p> <p>Type-dependent messages let you define a different message for numeric, string, arrays and files. The language entry used will be &quot;validation.rules.rulename.type&quot;</p> <table><thead><tr><th>Parameters</th> <th>Return</th></tr></thead> <tbody><tr><td><code>name string</code></td> <td><code>void</code></td></tr> <tr><td><code>rule *validation.RuleDefinition</code></td> <td></td></tr></tbody></table> <p><strong>Example:</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    82      validation<span class="token punctuation">.</span><span class="token function">AddRule</span><span class="token punctuation">(</span><span class="token string">&quot;custom_format&quot;</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>validation<span class="token punctuation">.</span>RuleDefinition<span class="token punctuation">{</span>
    83          Function<span class="token punctuation">:</span>           validateCustomFormat<span class="token punctuation">,</span>
    84          RequiredParameters<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// Ensure the rule has at least one parameter</span>
    85  	<span class="token punctuation">}</span><span class="token punctuation">)</span>
    86  <span class="token punctuation">}</span>
    87  </code></pre></div><p>The <strong>RuleDefinition</strong> struct is defined as follows:</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">type</span> RuleDefinition <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    88  
    89  	<span class="token comment">// The Function field is the function that will be executed</span>
    90  	Function RuleFunc
    91  
    92  	<span class="token comment">// The minimum amount of parameters</span>
    93  	RequiredParameters <span class="token builtin">int</span>
    94  
    95  	<span class="token comment">// A type rule is a rule that checks if a field has a certain type</span>
    96  	<span class="token comment">// and can convert the raw value to a value fitting. For example, the UUID</span>
    97  	<span class="token comment">// rule is a type rule because it takes a string as input, checks if it's a</span>
    98  	<span class="token comment">// valid UUID and converts it to a &quot;uuid.UUID&quot;.</span>
    99  	IsType <span class="token builtin">bool</span>
   100  
   101  	<span class="token comment">// Type-dependent rules are rules that can be used with different field types</span>
   102      <span class="token comment">// (numeric, string, arrays and files) and have a different validation messages</span>
   103      <span class="token comment">// depending on the type.</span>
   104  	<span class="token comment">// The language entry used will be &quot;validation.rules.rulename.type&quot;</span>
   105  	IsTypeDependent <span class="token builtin">bool</span>
   106  <span class="token punctuation">}</span>
   107  </code></pre></div><h3 id="adding-a-message-to-your-rule"><a href="#adding-a-message-to-your-rule" class="header-anchor">#</a> Adding a message to your rule</h3> <p>Finally, you may want to add a custom validation message for your rule so the client knows what's wrong with its request. Open <code>resources/lang/en-US/rules.json</code> and add an entry with the name of your rule as key:</p> <div class="language-json extra-class"><pre class="language-json"><code><span class="token punctuation">{</span>
   108      <span class="token comment">//...</span>
   109      <span class="token property">&quot;custom_format&quot;</span><span class="token operator">:</span> <span class="token string">&quot;The :field format is invalid.&quot;</span><span class="token punctuation">,</span>
   110  <span class="token punctuation">}</span>
   111  </code></pre></div><p>If you are supporting multiple languages, don't forget to add this to your other <code>rules.json</code> files too.</p> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>Learn more about validation rules messages in the <a href="/goyave/guide/advanced/localization.html#rules">Localization documentation</a>.</p></div> <h4 id="validation-getfieldtype"><a href="#validation-getfieldtype" class="header-anchor">#</a> validation.GetFieldType</h4> <p><span class="badge tip" style="vertical-align:top;" data-v-15b7b770>Since v2.0.0</span></p> <p>returns the non-technical type of the given <code>value</code> interface.
   112  This is used by validation rules to know if the input data is a candidate
   113  for validation or not and is especially useful for type-dependent rules.</p> <ul><li><code>numeric</code> if the value is an int, uint or a float</li> <li><code>string</code> if the value is a string</li> <li><code>array</code> if the value is a slice</li> <li><code>file</code> if the value is a slice of <code>filesystem.File</code></li> <li><code>unsupported</code> otherwise</li></ul> <table><thead><tr><th>Parameters</th> <th>Return</th></tr></thead> <tbody><tr><td><code>value interface{}</code></td> <td><code>string</code></td></tr></tbody></table> <p><strong>Example:</strong></p> <div class="language-go extra-class"><pre class="language-go"><code>validation<span class="token punctuation">.</span><span class="token function">GetFieldType</span><span class="token punctuation">(</span><span class="token string">&quot;foo&quot;</span><span class="token punctuation">)</span> <span class="token comment">// &quot;string&quot;</span>
   114  validation<span class="token punctuation">.</span><span class="token function">GetFieldType</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment">// &quot;numeric&quot;</span>
   115  validation<span class="token punctuation">.</span><span class="token function">GetFieldType</span><span class="token punctuation">(</span><span class="token number">2.4</span><span class="token punctuation">)</span> <span class="token comment">// &quot;numeric&quot;</span>
   116  validation<span class="token punctuation">.</span><span class="token function">GetFieldType</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// &quot;array&quot;</span>
   117  </code></pre></div><h2 id="validating-arrays"><a href="#validating-arrays" class="header-anchor">#</a> Validating arrays</h2> <p><span class="badge tip" style="vertical-align:top;" data-v-15b7b770>Since v2.1.0</span></p> <p>Validating arrays is easy. All the validation rules, <strong>except the file-related rules and the <code>confirmed</code> rule</strong>, can be applied to array values using the prefix <code>&gt;</code>. When array values are validated, <strong>all of them</strong> must pass the validation.</p> <p><strong>Example:</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">var</span> arrayValidation <span class="token operator">=</span> validation<span class="token punctuation">.</span>RuleSet<span class="token punctuation">{</span>
   118      <span class="token string">&quot;array&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;array:string&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;between:1,5&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&gt;email&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&gt;max:128&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   119  <span class="token punctuation">}</span>
   120  </code></pre></div><p>In this example, we are validating an array of one to five email addresses, which can't be longer than 128 characters.</p> <h3 id="n-dimensional-arrays"><a href="#n-dimensional-arrays" class="header-anchor">#</a> N-dimensional arrays</h3> <p>You can validate n-dimensional arrays.</p> <p><strong>Example:</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">var</span> arrayValidation <span class="token operator">=</span> RuleSet<span class="token punctuation">{</span>
   121      <span class="token string">&quot;array&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;array&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&gt;array&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&gt;&gt;array:numeric&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&gt;max:3&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&gt;&gt;&gt;max:4&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   122  <span class="token punctuation">}</span>
   123  </code></pre></div><p>In this example, we are validating a three-dimensional array of numeric values. The second dimension must be made of arrays with a size of 3 or less. The third dimension must contain numbers inferior or equal to 4. The following JSON input passes the validation:</p> <div class="language-json extra-class"><pre class="language-json"><code><span class="token punctuation">{</span>
   124      <span class="token property">&quot;array&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span>
   125          <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">1.42</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">0.6</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
   126          <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">0.6</span><span class="token punctuation">,</span> <span class="token number">1.43</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
   127      <span class="token punctuation">]</span>
   128  <span class="token punctuation">}</span>
   129  </code></pre></div><h2 id="placeholders"><a href="#placeholders" class="header-anchor">#</a> Placeholders</h2> <p>Validation messages can use placeholders to inject dynamic values in the validation error message. For example, in the <code>rules.json</code> language file:</p> <div class="language-json extra-class"><pre class="language-json"><code><span class="token property">&quot;between.string&quot;</span><span class="token operator">:</span> <span class="token string">&quot;The :field must be between :min and :max characters.&quot;</span>
   130  </code></pre></div><p>Here, the <code>:field</code> placeholder will be replaced by the field name, <code>:min</code>  with the first parameter and <code>:max</code> with the second parameter, effectively giving the following result:</p> <div class="language- extra-class"><pre class="language-text"><code>The password must be between 6 and 32 characters. 
   131  </code></pre></div><p>Placeholders are <strong>replacer functions</strong>. In fact, <code>validation.Placeholder</code> is an alias for <code>func(string, string, []string, string) string</code>. These functions should return the value to replace the placeholder with.</p> <p><strong>Example:</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">simpleParameterPlaceholder</span><span class="token punctuation">(</span>field <span class="token builtin">string</span><span class="token punctuation">,</span> rule <span class="token builtin">string</span><span class="token punctuation">,</span> parameters <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">,</span> language <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span>
   132  	<span class="token keyword">return</span> parameters<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
   133  <span class="token punctuation">}</span>
   134  </code></pre></div><hr> <p>Placeholders are implemented in the <code>http/validation/placeholder.go</code>. To register a custom placeholder, use the <code>validation.SetPlaceholder()</code> function, preferably in the <code>init()</code> function of your <code>placeholder.go</code> file.</p> <h4 id="validation-setplaceholder"><a href="#validation-setplaceholder" class="header-anchor">#</a> validation.SetPlaceholder</h4> <p>Sets the replacer function for the given placeholder. Don't include the colon prefix in the placeholder name.</p> <p>If a placeholder with this name already exists, the latter will be overridden.</p> <table><thead><tr><th>Parameters</th> <th>Return</th></tr></thead> <tbody><tr><td><code>placeholderName string</code></td> <td><code>void</code></td></tr> <tr><td><code>replacer validation.Placeholder</code></td> <td></td></tr></tbody></table> <p><strong>Example:</strong></p> <div class="language-go extra-class"><pre class="language-go"><code>validation<span class="token punctuation">.</span><span class="token function">SetPlaceholder</span><span class="token punctuation">(</span><span class="token string">&quot;min&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>field <span class="token builtin">string</span><span class="token punctuation">,</span> rule <span class="token builtin">string</span><span class="token punctuation">,</span> parameters <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">,</span> language <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span>
   135    	<span class="token keyword">return</span> parameters<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token comment">// Replace &quot;:min&quot; by the first parameter in the rule definition</span>
   136  <span class="token punctuation">}</span><span class="token punctuation">)</span>
   137  </code></pre></div><h3 id="available-placeholders"><a href="#available-placeholders" class="header-anchor">#</a> Available placeholders</h3> <h4 id="field"><a href="#field" class="header-anchor">#</a> :field</h4> <p><code>:field</code> is replaced by the name of the field. If it exists, the replacer with favor the language lines in <code>fields.json</code>.</p> <h4 id="other"><a href="#other" class="header-anchor">#</a> :other</h4> <p><code>:other</code> is replaced by the name of the field given as first parameter in the rule definition. If it exists, the replacer with favor the language lines in <code>fields.json</code>.</p> <p>For example, the <code>same:password_confirmation</code> rule compares two fields together and returns the following message if the validation fails:</p> <div class="language- extra-class"><pre class="language-text"><code>The :field and the :other must match.
   138  
   139  The password and the password confirmation must match.
   140  </code></pre></div><h4 id="value"><a href="#value" class="header-anchor">#</a> :value</h4> <p><code>:value</code> is replaced by the first parameter of the rule definition.</p> <h4 id="values"><a href="#values" class="header-anchor">#</a> :values</h4> <p><code>:values</code> is replaced by a concatenation of all rule parameters, joined by a comma.</p> <h4 id="min"><a href="#min" class="header-anchor">#</a> :min</h4> <p><code>:min</code> is replaced by the first parameter of the rule definition.</p> <h4 id="max"><a href="#max" class="header-anchor">#</a> :max</h4> <p><code>:max</code> is replaced by the first parameter of the rule definition, or the second if the rule name contains <code>between</code>.</p> <h4 id="version"><a href="#version" class="header-anchor">#</a> :version</h4> <p><code>:version</code> is replaced by a concatenation of <code>v</code> and the first parameter of the rule definition, or by an empty string if the rule doesn't have any parameter.</p> <p>For example, for the <code>UUID:4</code> rule, the result would be <code>v4</code>.</p> <h4 id="date"><a href="#date" class="header-anchor">#</a> :date</h4> <p><code>:date</code> is replaced by the first parameter of the rule definition. If the first parameter is a field name, <code>:date</code> will be replaced with the name of the field in the same way as the <code>:other</code> placeholder.</p> <h4 id="max-date"><a href="#max-date" class="header-anchor">#</a> :max_date</h4> <p><code>:max_date</code> is replaced by the second parameter of the rule definition. If the second parameter is a field name, <code>:max_date</code> will be replaced with the name of the field in the same way as the <code>:other</code> placeholder.</p> <h2 id="manual-validation"><a href="#manual-validation" class="header-anchor">#</a> Manual validation</h2> <p><span class="badge tip" style="vertical-align:top;" data-v-15b7b770>Since v2.1.0</span></p> <p>You may need to validate some data manually as part of your business logic. You can use the Goyave validator to do so.</p> <h4 id="validation-validate"><a href="#validation-validate" class="header-anchor">#</a> validation.Validate</h4> <p>Validate the given data with the given rule set. If all validation rules pass, returns an empty <code>validation.Errors</code>.</p> <p>The third parameter (<code>isJSON</code>) tells the function if the data comes from a JSON request. This is used to return the correct message if the given data is <code>nil</code> and to correctly handle arrays in url-encoded requests.</p> <p>The last parameter (<code>language</code>) sets the language of the validation error messages.</p> <table><thead><tr><th>Parameters</th> <th>Return</th></tr></thead> <tbody><tr><td><code>data map[string]interface{}</code></td> <td><code>validation.Errors</code></td></tr> <tr><td><code>rules validation.Ruler</code></td> <td></td></tr> <tr><td><code>isJSON bool</code></td> <td></td></tr> <tr><td><code>language string</code></td> <td></td></tr></tbody></table> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <ul><li><code>validation.Errors</code> is an alias for <code>map[string][]string</code>. The key represents the field name and the associated slice contains all already translated validation error messages for this field.</li> <li><code>validation.Ruler</code> is an interface that both <code>validation.RuleSet</code> and <code>validation.Rules</code> implement.</li></ul></div> <p><strong>Example:</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">Store</span><span class="token punctuation">(</span>response <span class="token operator">*</span>goyave<span class="token punctuation">.</span>Response<span class="token punctuation">,</span> request <span class="token operator">*</span>goyave<span class="token punctuation">.</span>Request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   141      data <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span>
   142  		<span class="token string">&quot;string&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;hello world&quot;</span><span class="token punctuation">,</span>
   143  		<span class="token string">&quot;number&quot;</span><span class="token punctuation">:</span> <span class="token number">42</span><span class="token punctuation">,</span>
   144  	<span class="token punctuation">}</span>
   145  
   146  	errors <span class="token operator">:=</span> validation<span class="token punctuation">.</span><span class="token function">Validate</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> validation<span class="token punctuation">.</span>RuleSet<span class="token punctuation">{</span>
   147  		<span class="token string">&quot;string&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   148  		<span class="token string">&quot;number&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;numeric&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;min:10&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   149  	<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> request<span class="token punctuation">.</span>Lang<span class="token punctuation">)</span>
   150  
   151  	<span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>errors<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token punctuation">{</span>
   152  		response<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusUnprocessableEntity<span class="token punctuation">,</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>validation<span class="token punctuation">.</span>Errors<span class="token punctuation">{</span><span class="token string">&quot;validationError&quot;</span><span class="token punctuation">:</span> errors<span class="token punctuation">}</span><span class="token punctuation">)</span>
   153  		<span class="token keyword">return</span>
   154  	<span class="token punctuation">}</span>
   155  
   156  	<span class="token comment">// data can be safely used from here</span>
   157  	<span class="token comment">// ...</span>
   158  <span class="token punctuation">}</span>
   159  </code></pre></div><h2 id="alternative-syntax"><a href="#alternative-syntax" class="header-anchor">#</a> Alternative syntax</h2> <p><span class="badge tip" style="vertical-align:top;" data-v-15b7b770>Since v3.0.0</span></p> <p>Internally, <code>validation.RuleSet</code> is parsed and replaced with a more complex structure the first time it is used: <code>validation.Rules</code>. This avoids having to parse rules everytime a request is received. Both <code>validation.RuleSet</code> and <code>validation.Rules</code> can be used when calling <code>validation.Validate()</code>, as they both implement the <code>validation.Ruler</code> interface. The syntax for <code>validation.Rules</code> is significantly more verbose and harder to read,</p> <p>Here is an example of rule definition using <code>validation.Rules</code> instead of <code>validation.RuleSet</code>:</p> <div class="language-go extra-class"><pre class="language-go"><code>rules <span class="token operator">:=</span> <span class="token operator">&amp;</span>validation<span class="token punctuation">.</span>Rules<span class="token punctuation">{</span>
   160      Fields<span class="token punctuation">:</span> validation<span class="token punctuation">.</span>FieldMap<span class="token punctuation">{</span>
   161          <span class="token string">&quot;email&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
   162              Rules<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>validation<span class="token punctuation">.</span>Rule<span class="token punctuation">{</span>
   163                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;required&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   164                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   165                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;between&quot;</span><span class="token punctuation">,</span> Params<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">&quot;3&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;125&quot;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   166                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;email&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   167              <span class="token punctuation">}</span><span class="token punctuation">,</span>
   168          <span class="token punctuation">}</span><span class="token punctuation">,</span>
   169          <span class="token string">&quot;password&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
   170              Rules<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>validation<span class="token punctuation">.</span>Rule<span class="token punctuation">{</span>
   171                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;required&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   172                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   173                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;between&quot;</span><span class="token punctuation">,</span> Params<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">&quot;6&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;64&quot;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   174                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;confirmed&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   175              <span class="token punctuation">}</span><span class="token punctuation">,</span>
   176          <span class="token punctuation">}</span><span class="token punctuation">,</span>
   177          <span class="token string">&quot;info&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
   178              Rules<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>validation<span class="token punctuation">.</span>Rule<span class="token punctuation">{</span>
   179                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;nullable&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   180                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;array&quot;</span><span class="token punctuation">,</span> Params<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">&quot;string&quot;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   181                  <span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">&quot;min&quot;</span><span class="token punctuation">,</span> Params<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">&quot;2&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span> ArrayDimension<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   182              <span class="token punctuation">}</span><span class="token punctuation">,</span>
   183          <span class="token punctuation">}</span><span class="token punctuation">,</span>
   184      <span class="token punctuation">}</span><span class="token punctuation">,</span>
   185  <span class="token punctuation">}</span>
   186  
   187  <span class="token comment">// Is the same as:</span>
   188  set <span class="token operator">:=</span> validation<span class="token punctuation">.</span>RuleSet<span class="token punctuation">{</span>
   189      <span class="token string">&quot;email&quot;</span><span class="token punctuation">:</span>    <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;between:3,125&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;email&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   190      <span class="token string">&quot;password&quot;</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">&quot;required&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;between:6,64&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;confirmed&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   191      <span class="token string">&quot;info&quot;</span><span class="token punctuation">:</span>     <span class="token punctuation">{</span><span class="token string">&quot;nullable&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;array:string&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&gt;min:2&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
   192  <span class="token punctuation">}</span>
   193  </code></pre></div><div class="custom-block tip"><p class="custom-block-title">TIP</p> <ul><li><code>validation.FieldMap</code> is an alias for <code>map[string]*validation.Field</code></li> <li>You can use this syntax if you need commas to be part of the values of a rule parameters.</li></ul></div></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/System-Glitch/goyave/edit/master/docs_src/src/guide/basics/validation.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
   194        ←
   195        <a href="/goyave/guide/basics/database.html" class="prev">
   196          Database
   197        </a></span> <span class="next"><a href="/goyave/guide/advanced/helpers.html">
   198          Helpers
   199        </a>
   200        →
   201      </span></p></div> </main></div><div class="global-ui"><!----></div></div>
   202      <script src="/goyave/assets/js/app.092490a7.js" defer></script><script src="/goyave/assets/js/4.75a9cc68.js" defer></script><script src="/goyave/assets/js/1.121dd9ed.js" defer></script><script src="/goyave/assets/js/23.931b2034.js" defer></script><script src="/goyave/assets/js/5.c83f1192.js" defer></script>
   203    </body>
   204  </html>