github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/docs/guide/architecture-concepts.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>Architecture Concepts | 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="Architecture concepts - Goyave">
    16      <meta name="twitter:title" content="Architecture concepts - Goyave">
    17      <meta name="title" content="Architecture concepts - 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/16.ed66719e.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/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/23.931b2034.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/5.c83f1192.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 open"><span>Guide</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/goyave/guide/" aria-current="page" class="sidebar-link">Introduction</a></li><li><a href="/goyave/guide/changelog.html" class="sidebar-link">Changelog</a></li><li><a href="/goyave/guide/installation.html" class="sidebar-link">Installation</a></li><li><a href="/goyave/guide/upgrade-guide.html" class="sidebar-link">Upgrade Guide</a></li><li><a href="/goyave/guide/configuration.html" class="sidebar-link">Configuration</a></li><li><a href="/goyave/guide/architecture-concepts.html" aria-current="page" class="active sidebar-link">Architecture Concepts</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/goyave/guide/architecture-concepts.html#introduction" class="sidebar-link">Introduction</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/architecture-concepts.html#terminology" class="sidebar-link">Terminology</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/architecture-concepts.html#lifecycle" class="sidebar-link">Lifecycle</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/architecture-concepts.html#directory-structure" class="sidebar-link">Directory structure</a></li><li class="sidebar-sub-header"><a href="/goyave/guide/architecture-concepts.html#database" class="sidebar-link">Database</a></li></ul></li><li><a href="/goyave/guide/deployment.html" class="sidebar-link">Deployment</a></li><li><a href="/goyave/guide/contribution-guide.html" class="sidebar-link">Contributing to Goyave</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>The Basics</span> <span class="arrow right"></span></p> <!----></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="architecture-concepts"><a href="#architecture-concepts" class="header-anchor">#</a> Architecture Concepts</h1> <p></p><div class="table-of-contents"><ul><li><a href="#introduction">Introduction</a></li><li><a href="#terminology">Terminology</a></li><li><a href="#lifecycle">Lifecycle</a><ul><li><a href="#server">Server</a></li><li><a href="#requests">Requests</a></li></ul></li><li><a href="#directory-structure">Directory structure</a><ul><li><a href="#database-directory">Database directory</a></li><li><a href="#http-directory">HTTP directory</a></li><li><a href="#resources-directory">Resources directory</a></li><li><a href="#test-directory">Test directory</a></li><li><a href="#custom-directories">Custom directories</a></li></ul></li><li><a href="#database">Database</a></li></ul></div><p></p> <h2 id="introduction"><a href="#introduction" class="header-anchor">#</a> Introduction</h2> <p>Understanding your development tools and knowing what happens in the background is crucial. Mastering your tools and environment incredibly decreases the risk of errors, the ease of debugging and helps making your code work in harmony with the framework. The goal of this section is to give you an overview of the general functioning and design of the framework, to make you more comfortable and confident using it.</p> <h2 id="terminology"><a href="#terminology" class="header-anchor">#</a> Terminology</h2> <p>This section will briefly explain the technical words used in the following sections.</p> <p><strong>Lifecycle</strong>: An execution from start to finish, with intermediary steps.</p> <p><strong>Framework core</strong>: Features and behaviors executed internally and that are invisible to the application developer.</p> <p><strong>Handler</strong>: A function receiving incoming requests and a response writer. Multiple handlers can be executed for the same request.</p> <p><strong>Router</strong>: The root-level handler responsible for the execution of the correct controller handler.</p> <p><strong>Route</strong>: A URI definition linked to a controller handler. If a request matches the definition, the router will execute the associated controller handler.</p> <p><strong>Controller</strong>: A source file implementing the business logic linked to a specific resource and associated routes.</p> <p><strong>Middleware</strong>: A handler executed before controller handlers. Middleware can intercept the request, modify its data, and send a response before the controller handler is reached.</p> <p><strong>Application</strong>: A program using the Goyave framework as a library.</p> <p><strong>Model</strong>: A structure reflecting a database table structure. An instance of a model is a single database record.</p> <p><strong>Seeder</strong>: A function which creates a number of random records in the database.</p> <h2 id="lifecycle"><a href="#lifecycle" class="header-anchor">#</a> Lifecycle</h2> <h3 id="server"><a href="#server" class="header-anchor">#</a> Server</h3> <p>The very first step of the server lifecycle is the <strong>server setup</strong>, taking place when you call <code>goyave.Start(route.Register)</code> in your application's main function.</p> <p>Goyave starts by loading the <a href="/goyave/guide/configuration.html">configuration</a> file from the core of the framework. The application's configuration file is then loaded, overriding the default values.</p> <p>The second step of the initialization takes a very similar approach to load the <a href="./advanced/localization.hmtl">language</a> files. The <code>en-US</code> language is available by default inside the framework and is used as the default language. When it's loaded, the framework will look for custom language files inside the working directory and will override the <code>en-US</code> language entries if needed.</p> <p>Then, if enabled, the automatic migrations are run, thus creating the <a href="/goyave/guide/basics/database.html">database</a> connection pool. If the automatic migrations are not enabled, no connection to the database will be established until the application requires one.</p> <p>That is only now that <a href="/goyave/guide/basics/routing.html">routes</a> are registered using the route registrer provided to the <code>Start()</code> function. That means that at this registrer has already access to all the configuration and language features, which can be handy if you want to generate different routes based on the languages your application supports.</p> <p>Finally, the framework starts listening for incoming HTTP requests and serves them. The server also listens for interruption and termination signals so it can finish serving ongoing requests before shutting down gracefully. In the next section, we will get into more details about the lifecycle of each request.</p> <h3 id="requests"><a href="#requests" class="header-anchor">#</a> Requests</h3> <p>When an incoming request is received, it's first passed through the router so your server knows which handler to execute when a user requests a specific URI. Then, the framework's internal handler creates a <code>goyave.Request</code> object and a <code>goyave.Response</code> object from the raw request. These two objects are fundamental features of the framework as you are going to use them to retrieve the requests' data and write your responses.</p> <p>Before executing the handler, the middleware are executed. The framework features a few core middleware, which are executed <strong>first</strong> and for all routes and all requests.</p> <h4 id="_1-recovery"><a href="#_1-recovery" class="header-anchor">#</a> 1. Recovery</h4> <p>The <strong>recovery</strong> middleware is executed. This middleware ensures that any unrecovered panic is handled. Instead of never returning a response in case of a panic, the server will then return an HTTP 500 Error. If debugging is enabled if the configuration, the response will contain the error message and the stacktrace will be printed in the console. It's important to keep this behavior in mind when handling errors in your handlers.</p> <h4 id="_2-parsing"><a href="#_2-parsing" class="header-anchor">#</a> 2. Parsing</h4> <p>The request is <strong>parsed</strong> by a second middleware. This middleware will automatically detect the request's body format based on the headers and attempt to parse it. If the request can't be parsed, the request's data is simply set to <code>nil</code>. This middleware supports JSON requests.</p> <h4 id="_3-language"><a href="#_3-language" class="header-anchor">#</a> 3. Language</h4> <p>The <code>Accept-Language</code> header is checked. If it's there, its value is parsed and the request's language attribute is set accordingly so localization is easy in the following handlers. If the header is missing, invalid, or asks for an unsupported language, the framework falls back to the default language defined in the configuration. Learn more <a href="/goyave/guide/advanced/localization.html">here</a>.</p> <h4 id="_4-application-middleware"><a href="#_4-application-middleware" class="header-anchor">#</a> 4. Application middleware</h4> <p>Application middleware are executed. These middleware are implemented and defined by the application developer. Note that some application middleware are already available in the framework. Learn more in the <a href="/goyave/guide/basics/middleware.html">middleware</a> section. At this stage of the lifecycle, the request is not validated yet, so application middleware can be used for authentication or automatic string trimming for example. Bear in mind that manipulating unvalidated data can be dangerous, especially in form-data where the data types are not converted by the validator yet.</p> <h4 id="_5-validation"><a href="#_5-validation" class="header-anchor">#</a> 5. Validation</h4> <p>The data is validated last. The validation middleware immediately passes if no rules have been defined for the current route, else, it check if the data parsing was successful. An automatic response is sent if that is not the case. The data is passed through the validator, which converts the data types and validates it. The request is stopped if the validation is not successful, and the validation errors are sent as a response. Be careful when working with unvalidated requests (which you should never do!) because if the request's parsing fails, <code>request.Data</code> will be <code>nil</code>.</p> <h4 id="_6-controller-handler"><a href="#_6-controller-handler" class="header-anchor">#</a> 6. Controller handler</h4> <p>If the request has not been stopped by a middleware, the controller handler is executed.
    42  If the controller handler didn't write anything as a response, an empty response with the HTTP status code 204 &quot;No Content&quot; is automatically sent, so you don't have to do it yourself.</p> <h4 id="_7-finalization"><a href="#_7-finalization" class="header-anchor">#</a> 7. Finalization</h4> <p>The <code>204 No Content</code> status is written if the response is empty and no status has been set. If a status code has been set but the body is empty, a <a href="/goyave/guide/advanced/status-handlers.html">status handler</a> will be executed if it exists.</p> <h2 id="directory-structure"><a href="#directory-structure" class="header-anchor">#</a> Directory structure</h2> <p>Goyave follows the principle of &quot;<strong>Convention is better than configuration</strong>&quot;. That means that the framework will attempt to automatically get the resources it needs from predefined directories.
    43  The typical and recommended directory structure for Goyave applications is as follows:</p> <pre class="vue-container"><code><p>.
    44  ├── database
    45  │   ├── model
    46  │   |   └── <em>...</em>
    47  │   └── seeder
    48  │       └── <em>...</em>
    49  ├── http
    50  │   ├── controller
    51  │   │   └── <em>...</em>
    52  │   ├── middleware
    53  │   │   └── <em>...</em>
    54  │   ├── validation (<em>optional</em>)
    55  │   │   ├── placeholder.go (<em>optional</em>)
    56  │   │   └── validation.go (<em>optional</em>)
    57  │   └── route
    58  │       └── routes.go
    59  │
    60  ├── resources
    61  │   ├── lang
    62  │   │   └── en-US (<em>language name</em>)
    63  │   │       ├── fields.json (<em>optional</em>)
    64  │   │       ├── locale.json (<em>optional</em>)
    65  │   │       └── rules.json (<em>optional</em>)
    66  │   ├── img (<em>optional</em>)
    67  │   │   └── <em>...</em>
    68  |   └── template (<em>optional</em>)
    69  |       └── <em>...</em>
    70  │
    71  ├── test
    72  |   └── <em>...</em>
    73  |
    74  ├── .gitignore
    75  ├── config.json
    76  ├── go.mod
    77  └── kernel.go</p>
    78  </code></pre><h3 id="database-directory"><a href="#database-directory" class="header-anchor">#</a> Database directory</h3> <p>The <code>database</code> directory stores source files related to the database. If you don't want to use auto-migrations, you can also store SQL scripts there. This directory can also contain database-related code such as repositories, if you want to use this pattern.</p> <p>Each model should have its own file in the <code>model</code> package.</p> <p>Each seeder should have its own file in the <code>seeder</code> package.</p> <h3 id="http-directory"><a href="#http-directory" class="header-anchor">#</a> HTTP directory</h3> <p>The <code>http</code> directory contains all the HTTP-related code. This is where most of your code will be written.</p> <h4 id="http-controllers"><a href="#http-controllers" class="header-anchor">#</a> HTTP controllers</h4> <p>The <code>http/controller</code> directory contains the controller packages. Each feature should have its own package. For example, if you have a controller handling user registration, user profiles, etc, you should create a <code>http/controller/user</code> package. Controller packages typically contain at least two files:</p> <pre class="vue-container"><code><p>controller
    79  └── user
    80      ├── user.go
    81      └── request.go</p>
    82  </code></pre><p>The <code>user.go</code> file contains the controller hanlders, while the <code>request.go</code> file contains the validation rules for each of them.</p> <p>Creating a package for each feature has the advantage of cleaning up route definitions a lot and helps keeping a clean structure for your project.</p> <p>Learn more about controllers <a href="/goyave/guide/basics/controllers.html">here</a>, and about validation <a href="/goyave/guide/basics/validation.html">here</a>.</p> <h4 id="http-middleware"><a href="#http-middleware" class="header-anchor">#</a> HTTP middleware</h4> <p>The <code>http/middleware</code> directory contains the application middleware. Each middleware should have its own file. Learn more <a href="/goyave/guide/basics/middleware.html">here</a>.</p> <h4 id="http-validation"><a href="#http-validation" class="header-anchor">#</a> HTTP validation</h4> <p>The <code>http/validation</code> directory contains the custom validation-related code.</p> <p>This directory can contain a <code>validation.go</code> file, which will define custom validation rules. Learn more <a href="/goyave/guide/basics/validation.html#custom-rules">here</a>.</p> <p>This directory can also contain a <code>placeholder.go</code> file, which will define validation rule messages placeholders. Learn more <a href="/goyave/guide/basics/validation.html#placeholders">here</a>.</p> <p>This package is usually imported in <code>kernel.go</code> to call the <code>init()</code> functions defined in the two files mentionned above.</p> <h4 id="http-routes"><a href="#http-routes" class="header-anchor">#</a> HTTP Routes</h4> <p>The <code>http/route</code> directory contains the routes définitions. By default, all routes are registered in the <code>route.go</code> file, but for bigger projects, split the route definitions into multiple files.</p> <h3 id="resources-directory"><a href="#resources-directory" class="header-anchor">#</a> Resources directory</h3> <p>The <code>resources</code> directory is meant to store static resources such as images, HTML documents and language files. This directory shouldn't be used as a storage for dynamic content such as user profile pictures.</p> <h4 id="language-resources-directory"><a href="#language-resources-directory" class="header-anchor">#</a> Language resources directory</h4> <p>The <code>resources/lang</code> directory contains your application's supported languages and translations. Each language has its own directory and should be named with an <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" target="_blank" rel="noopener noreferrer">ISO 639-1<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> language code. You can also append a variant to your languages: <code>en-US</code>, <code>en-UK</code>, <code>fr-FR</code>, <code>fr-CA</code>, ... <strong>Case is important.</strong></p> <p>Each language directory contains three files. Each file is <strong>optional</strong>.</p> <ul><li><code>fields.json</code>: field names translations and field-specific rule messages.</li> <li><code>locale.json</code>: all other language lines.</li> <li><code>rules.json</code>: validation rules messages.</li></ul> <p>Learn more about localization <a href="/goyave/guide/advanced/localization.html">here</a>.</p> <h4 id="template-resources-directory"><a href="#template-resources-directory" class="header-anchor">#</a> Template resources directory</h4> <p>The <code>resources/template</code> directory contains your text and HTML templates. Learn more about template rendering <a href="/goyave/guide/basics/responses.html#response-render">here</a>. This directory can contain sub-directories.</p> <h3 id="test-directory"><a href="#test-directory" class="header-anchor">#</a> Test directory</h3> <p>This directory is a package for <strong>functional</strong> tests. Functional tests test your application from an outside perspective. That means that your functional tests will make direct HTTP requests to your application and check the result. Unit tests should be located next to your source files.</p> <h3 id="custom-directories"><a href="#custom-directories" class="header-anchor">#</a> Custom directories</h3> <p>You may add custom directories for your custom utilities, as they don't belong to any of the above directories. For example, if you develop a service manipulating images, the image processing code shouldn't be written in controller handlers, they are not part of the business logic. You would then create a <code>processing</code> directory, containing your code in <code>images.go</code> for example.</p> <h2 id="database"><a href="#database" class="header-anchor">#</a> Database</h2> <p>Database connections are managed by the framework and are long-lived. When the server shuts down, the database connections are closed automatically. So you don't have to worry about creating, closing or refreshing database connections in your application.</p> <p>If automatic migrations are enabled, all registered models at the time of startup will be auto-migrated. They must be registered before the server starts, ideally from an <code>init()</code> function next to each model definition.</p> <p>Learn more in the <a href="/goyave/guide/basics/database.html">database</a> section.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/System-Glitch/goyave/edit/master/docs_src/src/guide/architecture-concepts.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">
    83        ←
    84        <a href="/goyave/guide/configuration.html" class="prev">
    85          Configuration
    86        </a></span> <span class="next"><a href="/goyave/guide/deployment.html">
    87          Deployment
    88        </a>
    89        →
    90      </span></p></div> </main></div><div class="global-ui"><!----></div></div>
    91      <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/16.ed66719e.js" defer></script>
    92    </body>
    93  </html>