<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kaizar</title>
    <description>The latest articles on DEV Community by Kaizar (@kaizar).</description>
    <link>https://dev.to/kaizar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3264986%2F9d934dce-0511-448a-b22d-081033050de7.png</url>
      <title>DEV Community: Kaizar</title>
      <link>https://dev.to/kaizar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kaizar"/>
    <language>en</language>
    <item>
      <title>How to build a reliable web application with Elm, GraphQL, PostGraphile and PostgreSQL</title>
      <dc:creator>Kaizar</dc:creator>
      <pubDate>Sun, 22 Jun 2025 11:53:14 +0000</pubDate>
      <link>https://dev.to/kaizar/how-to-build-a-reliable-web-application-with-elm-graphql-postgraphile-and-postgresql-427n</link>
      <guid>https://dev.to/kaizar/how-to-build-a-reliable-web-application-with-elm-graphql-postgraphile-and-postgresql-427n</guid>
      <description>&lt;p&gt;In this tutorial, we will create a tiny imageboard.&lt;/p&gt;

&lt;p&gt;The features will be very simple: visitors can see the list of images posted, and some editors will be able to add, modify, or remove images thanks of the GraphQL IDE named &lt;a href="https://github.com/graphql/graphiql" rel="noopener noreferrer"&gt;GraphiQL&lt;/a&gt;. I will explain more about GraphiQL later in this article.&lt;/p&gt;

&lt;p&gt;To summarize, an image has a &lt;em&gt;title&lt;/em&gt; and a &lt;em&gt;URL&lt;/em&gt; to the external website where it's hosted. To keep the application simple, no file is uploaded to  the server.&lt;/p&gt;

&lt;p&gt;Below you can see how this web application will look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F79278u6zo7dz799ao0ho.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F79278u6zo7dz799ao0ho.gif" alt="Demo" width="400" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A live demo version is also available &lt;a href="https://imageboard-u5u0.onrender.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can summarize the actions possible on this web application with the following use case diagram&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tdbzuuj87wxhyxh9m1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tdbzuuj87wxhyxh9m1i.png" alt="Use case diagram" width="800" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that all the UML diagrams presented in this article are made with &lt;a href="https://plantuml.com/" rel="noopener noreferrer"&gt;PlantUML&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The image stored in the database can be represented with the following entity-relationship diagram&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpujy9rniiy1di1wh7jhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpujy9rniiy1di1wh7jhg.png" alt="Entity relationship diagram" width="154" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's design the architecture!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6wmbcw9hxob8fg3r87g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6wmbcw9hxob8fg3r87g.png" alt="Architecture diagram" width="792" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Postgraphile will generate a GraphQL server from a PostgreSQL database. Then, the editors will be able to create, modify and remove images by communicating directly to GraphQL with GraphiQL. Finally, our Elm web application will allow the visitors to see all the images.&lt;/p&gt;

&lt;p&gt;Unlike the other diagrams, the architecture diagram was realized with &lt;a href="https://www.drawio.com/" rel="noopener noreferrer"&gt;draw.io&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the PostgreSQL database
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yqe26nsaw3ecr8cs4bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yqe26nsaw3ecr8cs4bg.png" alt="PostgreSQL logo" width="120" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; create a database. In this tutorial, we will name it &lt;em&gt;imageboard&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can use the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;createdb imageboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, connect to your database to create the table that stores the images.&lt;/p&gt;

&lt;p&gt;If you have a local PostgreSQL database instance, you can use &lt;em&gt;psql&lt;/em&gt; and execute this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql imageboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise, you can run the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql postgres://username:password@localhost/imageboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;em&gt;username&lt;/em&gt; and &lt;em&gt;password&lt;/em&gt; with the username and the password of your PostgreSQL server. And change &lt;em&gt;localhost&lt;/em&gt; by the hostname of your PostgreSQL server.&lt;/p&gt;

&lt;p&gt;Once connected, execute this SQL query&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;serial&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And insert a test data with this query&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'PostgreSQL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https://wiki.postgresql.org/images/a/a4/PostgreSQL_logo.3colors.svg'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create the back office with PostGraphile and GraphQL
&lt;/h2&gt;

&lt;p&gt;It's time to present to you an excellent tool that allows us to easily generate a GraphQL server from a PostgreSQL database. This tool is named &lt;a href="https://postgraphile.org/" rel="noopener noreferrer"&gt;Postgraphile&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftl14dg3naa8naid80pmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftl14dg3naa8naid80pmd.png" alt="PostGraphile GraphQL" width="342" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those who don't know, &lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; is an open-source query language and a runtime made to manipulate data through APIs.&lt;/p&gt;

&lt;p&gt;GraphQL can be used with HTTP, and a lot of programming language support it on client side or server side (JavaScript, Java, PHP, Swift...). You can see &lt;a href="https://graphql.org/community/tools-and-libraries/" rel="noopener noreferrer"&gt;here&lt;/a&gt; a detailed list of tools and libraries that allow us to use GraphQL.&lt;/p&gt;

&lt;p&gt;The main advantages of GraphQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A strongly typed language query and a strong type system. This is suitable for reducing the number of errors.&lt;/li&gt;
&lt;li&gt;A mechanism that fetches only what is needed by our application. This is useful when limiting the data sent through the network matters for reducing the latency. For example, on a mobile application that uses limited internet data.&lt;/li&gt;
&lt;li&gt;The possibility to get many resources in a single request.&lt;/li&gt;
&lt;li&gt;Powerful developer tools like GraphiQL.&lt;/li&gt;
&lt;li&gt;The possibility to evolve the API without versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why compared to the classical REST approach, GraphQL offers a lot of improvements 🚀.&lt;/p&gt;

&lt;p&gt;However, implementing an API that uses GraphQL to expose data from a database could take a lot of time. Especially if we want to adjust the database queries and the returned data from the database, regarding the field passed through the GraphQL queries.&lt;/p&gt;

&lt;p&gt;Hopefully, by using PostGraphile, this task will be done in a few minutes.&lt;/p&gt;

&lt;p&gt;Time to show you how!&lt;/p&gt;

&lt;p&gt;First, install PostGraphile. The &lt;a href="https://www.graphile.org/postgraphile/quick-start-guide/#install-postgraphile" rel="noopener noreferrer"&gt;quick start guide from the official website&lt;/a&gt; gives some instructions about that.&lt;/p&gt;

&lt;p&gt;We need to install &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; to have &lt;a href="https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager" rel="noopener noreferrer"&gt;npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;PostGraphile can be installed globally on your operating system, but in this tutorial, we will install it locally on the project folder.&lt;br&gt;
This approach will allow us to have multiple versions of PostGraphile depending on the project.&lt;/p&gt;

&lt;p&gt;Create a directory named &lt;em&gt;imageboard&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Inside this directory, run the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
npm install postgraphile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, execute this command to verify that PostGraphile is correctly installed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx postgraphile --help
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, execute PostGraphile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx postgraphile -c postgres://username:password@localhost/imageboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, note that you must replace &lt;em&gt;username&lt;/em&gt; and &lt;em&gt;password&lt;/em&gt; with the username and the password of your PostgreSQL server. If needed, change &lt;em&gt;localhost&lt;/em&gt; by the hostname of your PostgreSQL server.&lt;/p&gt;

&lt;p&gt;By default, the GraphQL server is exposed on the port 5000. You can navigate to the GraphiQL generated by opening the url &lt;a href="http://localhost:5000/graphiql" rel="noopener noreferrer"&gt;http://localhost:5000/graphiql&lt;/a&gt; on your web browser.&lt;/p&gt;

&lt;p&gt;GraphiQL is the IDE of GraphQL and allows us to execute queries and mutations (we will see that later) in a convenient way.&lt;/p&gt;

&lt;p&gt;It's also possible to improve the GraphiQL generated by PostGraphile with the option &lt;code&gt;--enhance-graphiql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, test that you can fetch the inserted image with GraphQL by running this query&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;allImages&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute it. This query must return the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allImages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PostgreSQL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://wiki.postgresql.org/images/a/a4/PostgreSQL_logo.3colors.svg"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrj2imsjbrp6reqihbnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrj2imsjbrp6reqihbnw.png" alt="GraphiQL query" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can learn more about GraphQL queries &lt;a href="https://graphql.org/learn/queries/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Editors can also use directly GraphiQL to add a new image.&lt;/p&gt;

&lt;p&gt;For writing data, GraphQL uses a mechanism named &lt;a href="https://graphql.org/learn/mutations/" rel="noopener noreferrer"&gt;mutation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the query editor, write this mutation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AddImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$createImageInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CreateImageInput&lt;/span&gt;&lt;span class="p"&gt;!)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$createImageInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the query variables panel, write this JSON text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"createImageInput"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PostGraphile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.graphile.org/images/postgraphile.optimized.svg"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute the mutation. The following data should be returned&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"createImage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PostGraphile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.graphile.org/images/postgraphile.optimized.svg"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjm0i4mr6kguyt1e0dtu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjm0i4mr6kguyt1e0dtu.png" alt="GraphiQL mutation" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all. The editors are now completely autonomous when they manipulate the images.&lt;/p&gt;

&lt;p&gt;Providing a back office web application with GraphiQL to some &lt;a href="https://en.wikipedia.org/wiki/Power_user" rel="noopener noreferrer"&gt;power users&lt;/a&gt;, like the editors, is useful. This strategy allows us to ship quickly a proof of concept, or a minimal viable product, to test your business without big developments, and make change faster without making a lot of refactorings. Basically you just have to change the schema of your database and regenerate a GraphQL server with PostGraphile 🪄.&lt;/p&gt;

&lt;p&gt;A lot of users don't need a sophisticated UI, and with some minimal documentations and help, they can execute GraphQL queries and mutations.&lt;br&gt;
Furthermore, as a developer, we can define some custom queries and mutations and give them to our power users.&lt;/p&gt;

&lt;p&gt;The following sequence diagrams summarize what we do with PostGraphile and GraphQL when the editor create, modify or remove an image:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8g64tiyf8cekvhv2as3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8g64tiyf8cekvhv2as3t.png" alt="Sequence diagram add the image" width="393" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that it's possible to use PostGraphile as a Node.js library. This method is very interesting when we want more control on our GraphQL server. For example, for some security reasons, it can be useful to add authentication by using Node.js.&lt;/p&gt;
&lt;h2&gt;
  
  
  Develop the front office as a web application with Elm
&lt;/h2&gt;

&lt;p&gt;GraphiQL is enough for the editors to add, modify or remove images. But it's not suitable for the visitors that want to see the list of images.&lt;/p&gt;

&lt;p&gt;One of the best ways to respond to this need is to create a custom web application.&lt;/p&gt;

&lt;p&gt;To do that, we will use the &lt;a href="https://elm-lang.org/" rel="noopener noreferrer"&gt;Elm&lt;/a&gt; programming language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mwoqki6d25vkurm7f86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mwoqki6d25vkurm7f86.png" alt="Elm logo" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Introduction to ELM
&lt;/h3&gt;

&lt;p&gt;Elm is a functional programming language specially made for the web. That means that an Elm application can be compiled to a JavaScript file and embedded to a HTML one.&lt;/p&gt;

&lt;p&gt;Elm provides a wide set of functions for manipulating the DOM, including DOM events, and for making HTTP requests.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://guide.elm-lang.org/architecture/" rel="noopener noreferrer"&gt;Elm architecture&lt;/a&gt; is built with these 3 concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Model&lt;/em&gt; to store the state of the application.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;View&lt;/em&gt; to use the state to render the HTML.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Update&lt;/em&gt; to update the state based on messages (usually fired by DOM events).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://guide.elm-lang.org/architecture/buttons.svg" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0o3vdrk4csh8wk1vjk7l.png" alt="Elm architecture" width="500" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some popular JavaScript libraries like &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt; has been inspired by this architecture.&lt;/p&gt;

&lt;p&gt;Elm can communicate with the outside world with &lt;a href="https://guide.elm-lang.org/effects/" rel="noopener noreferrer"&gt;Commands and Subscriptions&lt;/a&gt;. It's useful for making HTTP requests, for example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://guide.elm-lang.org/effects/diagrams/element.svg" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7b1aj5ybwuj50cpogfsg.png" alt="Elm Commands and Subscriptions" width="772" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I said before that Elm is a functional programming language. Precisely, Elm is a statically typed functional programming language that uses only pure functions.&lt;/p&gt;

&lt;p&gt;That means that Elm manipulates functions as first-class citizen, when oriented object programming languages, like Java or C++, manipulate mainly classes.&lt;/p&gt;

&lt;p&gt;Having pure functions means that each function only uses the values provided by parameters, therefore Elm functions don't use global variables or class attributes (that are like global variables, but that exist only in the scope of the class).&lt;/p&gt;

&lt;p&gt;The main benefits of the functional programming are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The reduction of the side effects when executing a function: a call to a function with the same parameters produces always the same result.&lt;/li&gt;
&lt;li&gt;The fact that Functions are more suitable for unit testing, because they use only values from its parameters.&lt;/li&gt;
&lt;li&gt;Better maintainability thanks of immutability of values. A variable has a value assigned but this value will never change. This is why it's more a constant rather than a variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Elm has also these advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No runtime exception, thanks of a mechanism that forces the developer to manage the unexpected behaviors of the application, with the concept of &lt;a href="https://guide.elm-lang.org/error_handling/" rel="noopener noreferrer"&gt;error handling&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Fearless refactoring, with the static typed and pure functional paradigm, and the compiler that produces helpful error messages.&lt;/li&gt;
&lt;li&gt;Great performance, with its implementation of virtual DOM.&lt;/li&gt;
&lt;li&gt;Small assets of the generated JavaScript thanks of the &lt;a href="https://elm-lang.org/news/small-assets-without-the-headache" rel="noopener noreferrer"&gt;optimizations&lt;/a&gt; provided by the compiler.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://guide.elm-lang.org/interop/" rel="noopener noreferrer"&gt;JavaScript interoperability&lt;/a&gt; with the flags, ports and custom elements.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Manipulate GraphQL with Elm
&lt;/h3&gt;

&lt;p&gt;It's possible to make plain HTTP requests for calling a GraphQL server from an Elm application.&lt;/p&gt;

&lt;p&gt;However, a powerful library exists to manipulate GraphQL from Elm. This library is called &lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/" rel="noopener noreferrer"&gt;elm-graphql&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Basically, this library uses our GraphQL server to generate &lt;a href="https://medium.com/open-graphql/type-safe-composable-graphql-in-elm-b3378cc8d021" rel="noopener noreferrer"&gt;Type-Safe and Composable Elm functions&lt;/a&gt; for manipulating GraphQL.&lt;/p&gt;

&lt;p&gt;Once you understand how to use the library, it's like magic, and you don't even need to care about raw HTTP requests and GraphQL details 🧙​.&lt;/p&gt;
&lt;h4&gt;
  
  
  Setup the application
&lt;/h4&gt;

&lt;p&gt;Now it's time to start to create the web application.&lt;/p&gt;

&lt;p&gt;To begin, install Elm using the &lt;a href="https://guide.elm-lang.org/install/elm" rel="noopener noreferrer"&gt;official guide instructions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Inside the &lt;em&gt;imageboard&lt;/em&gt; directory, run the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;elm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That will initialize our Elm application.&lt;/p&gt;

&lt;p&gt;Say yes when you are asked to create the &lt;em&gt;elm.json&lt;/em&gt; file. This file lists the Elm dependencies with the version of each package used by our application.&lt;/p&gt;

&lt;p&gt;Then, run this command to install &lt;em&gt;elm-graphql&lt;/em&gt; and confirm the modification of &lt;em&gt;elm.json&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;elm install dillonkearns/elm-graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the following command to generate the functions and types that manipule GraphQL (be sure that PostGraphile is still running)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx @dillonkearns/elm-graphql --base Imageboard http://localhost:5000/graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can change the hostname and the port according to how you run PostGraphile.&lt;/p&gt;

&lt;p&gt;A folder named &lt;em&gt;Imageboard&lt;/em&gt; should have been generated, inside the &lt;em&gt;src&lt;/em&gt; folder, and contains all our Elm source codes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlqc5pd9f3xi888kalk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlqc5pd9f3xi888kalk0.png" alt="GraphQL Elm" width="315" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, create a file named &lt;em&gt;Main.elm&lt;/em&gt; inside the &lt;em&gt;src&lt;/em&gt; folder.&lt;/p&gt;

&lt;p&gt;Let's start creating the scaffolding of our Elm application.&lt;/p&gt;

&lt;p&gt;First we create the &lt;em&gt;main&lt;/em&gt; function that calls the &lt;a href="https://package.elm-lang.org/packages/elm/browser/latest/Browser#element" rel="noopener noreferrer"&gt;Browser.element&lt;/a&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Program&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Browser.element&lt;/em&gt; is used instead of Browser.sandbox because the application need to communicate with the outside world. In particular when making HTTP requests to the GraphQL server.&lt;/p&gt;

&lt;p&gt;Then we create the init function that will be executed when the web application starts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;NotAsked&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first parameter of the init function represents the flags passed from outside the Elm application (for example from the HTML file that embed this application). It's useful in certain circumstances, but in our case, we can use the &lt;a href="https://en.wikipedia.org/wiki/Unit_type" rel="noopener noreferrer"&gt;unit type&lt;/a&gt; with the value &lt;em&gt;()&lt;/em&gt;. This type is the equivalent of the type void in some other programming languages.&lt;/p&gt;

&lt;p&gt;The init function returns a value of type &lt;em&gt;Model&lt;/em&gt; that represents the state of our application and returns a Command that should be executed.&lt;br&gt;
For the moment, we put &lt;em&gt;Cmd.none&lt;/em&gt;, but we will replace it by the function that makes a request to our GraphQL server.&lt;/p&gt;

&lt;p&gt;Note that &lt;em&gt;NotAsked&lt;/em&gt; is one of the possible variant of our Model that is defined bellow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- other imports are omitted&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;RemoteData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;-- other functions are omitted&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;parsedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsedData&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;Model&lt;/em&gt; is an alias (using &lt;a href="https://guide.elm-lang.org/types/type_aliases" rel="noopener noreferrer"&gt;type alias&lt;/a&gt;) for the type &lt;a href="https://package.elm-lang.org/packages/krisajenkins/remotedata/latest/RemoteData#RemoteData" rel="noopener noreferrer"&gt;RemoteData&lt;/a&gt; that represents a result of a request made to a server.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;krisajenkins/remotedata&lt;/em&gt; is an external library that works well with &lt;em&gt;dillonkearns/elm-graphql&lt;/em&gt; and simplify the management of HTTP requests.&lt;/p&gt;

&lt;p&gt;Because that &lt;em&gt;RemoteData&lt;/em&gt;, from the library &lt;em&gt;krisajenkins/remotedata&lt;/em&gt;, is a &lt;a href="https://guide.elm-lang.org/types/custom_types" rel="noopener noreferrer"&gt;custom type&lt;/a&gt;, it has some possible variants like &lt;em&gt;NotAsked&lt;/em&gt;, &lt;em&gt;Loading&lt;/em&gt;, &lt;em&gt;Failure&lt;/em&gt; or &lt;em&gt;Success&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To use this library, run the following command in the root application folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;elm install krisajenkins/remotedata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type &lt;em&gt;RemoteData&lt;/em&gt; has 2 &lt;a href="https://guide.elm-lang.org/types/reading_types#type-variables" rel="noopener noreferrer"&gt;type variables&lt;/a&gt; named &lt;em&gt;e&lt;/em&gt; and &lt;em&gt;a&lt;/em&gt;. These type variables respectively represent the type of data raised when the request fails (the variant &lt;em&gt;Failure&lt;/em&gt;), and the type of data raised when the request succeeds (the variant &lt;em&gt;Success&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;We create the type alias &lt;em&gt;Response&lt;/em&gt; for replacing the type variable &lt;em&gt;a&lt;/em&gt;, and the type alias &lt;em&gt;Error&lt;/em&gt; to replace the type variable &lt;em&gt;e&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Note that a type alias &lt;em&gt;Error&lt;/em&gt; is just a mock type, and take a type variable named &lt;em&gt;parsedData&lt;/em&gt; and return it. Once we use &lt;em&gt;elm-graphql&lt;/em&gt;, the type &lt;em&gt;Error&lt;/em&gt; should be replaced by the one provided by the library and that has the same type description.&lt;/p&gt;

&lt;p&gt;As you can see, when the value of the custom type RemoteData represents success, this success is linked to a type &lt;em&gt;Response&lt;/em&gt; that is an optional list of optional &lt;em&gt;Image&lt;/em&gt;. Optional types are managed with the &lt;a href="https://package.elm-lang.org/packages/elm-lang/core/latest/Maybe#Maybe" rel="noopener noreferrer"&gt;type Maybe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note that we can use directly the type &lt;em&gt;RemoteData (Error (Maybe (List (Maybe Image)))) (Maybe (List (Maybe Image)))&lt;/em&gt; instead of creating an intermediate type &lt;em&gt;Response&lt;/em&gt;. However, creating a type alias &lt;em&gt;Response&lt;/em&gt; avoids the duplication of the type &lt;em&gt;Maybe (List (Maybe Image))&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The type alias &lt;em&gt;Image&lt;/em&gt; is related to the table &lt;em&gt;image&lt;/em&gt; in our PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Add these instructions that manages the subscriptions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Sub&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Sub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we don't need to subscribe to some events, this function returns the value &lt;a href="https://package.elm-lang.org/packages/elm-lang/core/latest/Platform-Sub#none" rel="noopener noreferrer"&gt;Sub.none&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a simple function &lt;em&gt;update&lt;/em&gt; with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and a simple type &lt;em&gt;Msg&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the view, add the instructions bellow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;NotAsked&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Images are not yet asked."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Loading&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Images are loading..."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Failure&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There was a failure when we try to load the image."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No response could be retrieve from the server."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;div&lt;/span&gt;
                        &lt;span class="p"&gt;[]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Imageboard"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gallery"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="n"&gt;maybeImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;maybeImage&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No data could be retrieved from the server."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;img&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the top of the file, when we import modules, add these new imports to have the functions used by the view&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The view is relatively simple.&lt;/p&gt;

&lt;p&gt;The value of the model, that is an equivalent of &lt;em&gt;RemoteData (Error (Maybe (List (Maybe Image)))) (Maybe (List (Maybe Image)))&lt;/em&gt;, is tested using &lt;a href="https://guide.elm-lang.org/types/pattern_matching" rel="noopener noreferrer"&gt;pattern matching&lt;/a&gt; and a different HTML is render regarding the value of the variant that represents the state of the request made.&lt;/p&gt;

&lt;p&gt;Elm uses the package &lt;a href="https://package.elm-lang.org/packages/elm/html/latest/" rel="noopener noreferrer"&gt;elm/html&lt;/a&gt;, available in the standard library, for generating HTML tags with the good values for the HTML attributes.&lt;/p&gt;

&lt;p&gt;This package provides functions that generate almost every HTML tags and return a value of type &lt;a href="https://package.elm-lang.org/packages/elm/html/latest/Html#Html" rel="noopener noreferrer"&gt;Html&lt;/a&gt;, that is the type needed for the root view function.&lt;/p&gt;

&lt;p&gt;For rendering all the image, the &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/List#map" rel="noopener noreferrer"&gt;List.map&lt;/a&gt; function is used. In functional programming, instead of using loop with &lt;em&gt;for&lt;/em&gt; or &lt;em&gt;while&lt;/em&gt; keywords, we generally use &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/List#map" rel="noopener noreferrer"&gt;map&lt;/a&gt;, &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/List#foldl" rel="noopener noreferrer"&gt;fold&lt;/a&gt; or &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/List#filter" rel="noopener noreferrer"&gt;filter&lt;/a&gt; functions (or the equivalents).&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;map&lt;/em&gt; function takes for the first parameter a function to be executed on each element of the list, and for the second parameter the list himself. Here, the function &lt;em&gt;viewImage&lt;/em&gt; is executed and renders the HTML tag &lt;em&gt;img&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The file has now this content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;RemoteData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Program&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;NotAsked&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Sub&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Sub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;


&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;NotAsked&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Images are not yet asked."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Loading&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Images are loading..."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Failure&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There was a failure when we try to load the image."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No response could be retrieve from the server."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;div&lt;/span&gt;
                        &lt;span class="p"&gt;[]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Imageboard"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gallery"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="n"&gt;maybeImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;maybeImage&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No data could be retrieved from the server."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;img&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[]&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;parsedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsedData&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the root folder, create a file named &lt;em&gt;index.html&lt;/em&gt; with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Imageboard&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"styles.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"elm-node"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;elm-node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and a file named &lt;em&gt;styles.css&lt;/em&gt; with this content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f5f5f5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;32px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0077cc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.gallery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.gallery&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;350px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#0077cc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.gallery&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTML content references the CSS file and the JavaScript file that will be generated from the Elm compiler.&lt;/p&gt;

&lt;p&gt;The JavaScript instructions bellow are used to initialize the application generated from our Elm source code and embed it inside the tag div with the id &lt;em&gt;elm-node&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;elm-node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These CSS instructions enhance the design of the web application and provide some cool effects when the visitor moves his cursor over an image. &lt;/p&gt;

&lt;p&gt;Run the command &lt;code&gt;elm make src/Main.elm --output=main.js&lt;/code&gt; to generate the JavaScript file.&lt;/p&gt;

&lt;p&gt;Open with your web browser the file &lt;em&gt;index.html&lt;/em&gt; and observe the result.&lt;/p&gt;

&lt;p&gt;An empty page with only the text &lt;em&gt;Images are not yet asked.&lt;/em&gt; should be displayed.&lt;/p&gt;

&lt;p&gt;Now we will modify the source code to make the request to our GraphQL server.&lt;/p&gt;

&lt;p&gt;Change the &lt;em&gt;init&lt;/em&gt; function with the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Loading&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:5000/graphql"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will define the &lt;em&gt;makeRequest&lt;/em&gt; function later. Of course, change the URL to the GraphQL server if needed.&lt;/p&gt;

&lt;p&gt;Change also the &lt;em&gt;update&lt;/em&gt; function with this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;GotResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the type &lt;em&gt;Msg&lt;/em&gt; by the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;GotResponse&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we handle a message of the custom type &lt;em&gt;Msg&lt;/em&gt; with one variant: &lt;em&gt;GotResponse&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The next functions: &lt;em&gt;makeRequest&lt;/em&gt; and &lt;em&gt;query&lt;/em&gt; are the most difficult to understand.&lt;/p&gt;

&lt;p&gt;The goal of the function &lt;em&gt;makeRequest&lt;/em&gt; is to send the HTTP request, returned by the function &lt;em&gt;query&lt;/em&gt;, to our GraphQL server.&lt;/p&gt;

&lt;p&gt;The function &lt;em&gt;query&lt;/em&gt; has the goal to generate the GraphQL query seen before&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;allImages&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A function named &lt;em&gt;allImages&lt;/em&gt; has been generated with &lt;em&gt;elm-graphql&lt;/em&gt; and is available in the module &lt;em&gt;Imageboard.Query&lt;/em&gt;. This module regroups all root level GraphQL queries.&lt;/p&gt;

&lt;p&gt;This function takes for the first parameter a function that has the following signature &lt;em&gt;AllImagesOptionalArguments -&amp;gt; AllImagesOptionalArguments&lt;/em&gt;. This is because the &lt;em&gt;allImage&lt;/em&gt; query generated by PostGraphile takes some parameters that represent the &lt;em&gt;WHERE&lt;/em&gt; clause, the &lt;em&gt;ORDER BY&lt;/em&gt; clause and the &lt;em&gt;LIMIT&lt;/em&gt; clause of the SQL query performed. That's useful for paginating and filtering purposes.&lt;/p&gt;

&lt;p&gt;The second parameter of this function, and maybe the most difficult to understand, is a &lt;em&gt;SelectionSet decodesTo Imageboard.Object.ImagesConnection&lt;/em&gt;. The &lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-SelectionSet" rel="noopener noreferrer"&gt;SelectionSet&lt;/a&gt; is a type built by elm-graphql to select the fields that should be put in our query.&lt;/p&gt;

&lt;p&gt;With PostGraphile, it represents the &lt;em&gt;SELECT&lt;/em&gt; query.&lt;/p&gt;

&lt;p&gt;Because query in GraphQL can have sub queries as fields, each query function returns a &lt;em&gt;SelectionSet&lt;/em&gt; with a given scope and takes a &lt;em&gt;SelectionSet&lt;/em&gt; with another scope.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;SelectionSet&lt;/em&gt; takes the scope as the second parameter, and as a first parameter, it takes a function that will be used to transform the result of the GraphQL query, depending on the fields passed, to an Elm value or &lt;a href="https://guide.elm-lang.org/core_language#records" rel="noopener noreferrer"&gt;record&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before doing the &lt;em&gt;allImages&lt;/em&gt; query, start by implementing the &lt;em&gt;nodes&lt;/em&gt; query.&lt;/p&gt;

&lt;p&gt;The associated function of the &lt;em&gt;nodes&lt;/em&gt; query is the &lt;em&gt;nodes&lt;/em&gt; function available in the module named &lt;em&gt;Imageboard.Object.ImagesConnection&lt;/em&gt;. The signature of this function is &lt;em&gt;SelectionSet decodesTo Imageboard.Object.Image -&amp;gt; SelectionSet (List (Maybe decodesTo)) Imageboard.Object.ImagesConnection&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Once the &lt;em&gt;nodes&lt;/em&gt; function called with one value for the first parameter named &lt;em&gt;object____&lt;/em&gt;, it returns a value of type &lt;em&gt;SelectionSet (List (Maybe decodesTo)) Imageboard.Object&lt;/em&gt;. That's exactly what is needed for the function &lt;em&gt;allImages&lt;/em&gt;. The second parameter of this function, also named &lt;em&gt;object____&lt;/em&gt;, is a value of type &lt;em&gt;SelectionSet decodesTo Imageboard.Object.ImagesConnection&lt;/em&gt;. This is why we will call the function &lt;em&gt;nodes&lt;/em&gt; and pass the result of the function &lt;em&gt;allImages&lt;/em&gt; as its second parameter.&lt;/p&gt;

&lt;p&gt;But what should we pass to the first parameter of the function &lt;em&gt;allImages&lt;/em&gt;? Remember, we must pass a value of type &lt;em&gt;SelectionSet decodesTo Imageboard.Object.Image&lt;/em&gt; that represents the fields asked to GraphQL.&lt;br&gt;
In this query, we want the field &lt;em&gt;title&lt;/em&gt;, &lt;em&gt;url&lt;/em&gt; and &lt;em&gt;id&lt;/em&gt;.&lt;br&gt;
Hopefully &lt;em&gt;elm-graphql&lt;/em&gt; has generated the functions &lt;em&gt;title&lt;/em&gt;, &lt;em&gt;url&lt;/em&gt; and &lt;em&gt;id&lt;/em&gt; inside the module &lt;em&gt;Imageboard.Object.Image&lt;/em&gt;.&lt;br&gt;
The &lt;em&gt;title&lt;/em&gt; and &lt;em&gt;url&lt;/em&gt; functions return a value of type &lt;em&gt;SelectionSet String Imageboard.Object.Image&lt;/em&gt; whereas the function &lt;em&gt;id&lt;/em&gt; returns a value of type &lt;em&gt;SelectionSet Int Imageboard.Object.Image&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the function &lt;em&gt;nodes&lt;/em&gt; we should define a concrete type for the type variable &lt;em&gt;decodesTo&lt;/em&gt; of the first parameter &lt;em&gt;SelectionSet decodesTo Imageboard.Object.Image&lt;/em&gt;. This is here that we use the type &lt;em&gt;Image&lt;/em&gt; defined for the Model.&lt;/p&gt;

&lt;p&gt;To bind the generated functions &lt;em&gt;title&lt;/em&gt;, &lt;em&gt;url&lt;/em&gt; and &lt;em&gt;id&lt;/em&gt; to the type &lt;em&gt;Image&lt;/em&gt;, elm-graphql provides a function named &lt;em&gt;map3&lt;/em&gt; that takes a function that creates a value of a given type, with this signature &lt;em&gt;(decodesTo1 -&amp;gt; decodesTo2 -&amp;gt; decodesTo3 -&amp;gt; decodesToCombined) -&amp;gt; SelectionSet decodesTo1 scope -&amp;gt; SelectionSet decodesTo2 scope -&amp;gt; SelectionSet decodesTo3 scope -&amp;gt; SelectionSet decodesToCombined scope&lt;/em&gt;, and 3 other parameters of respectively types &lt;em&gt;SelectionSet decodesTo1 scope&lt;/em&gt;, &lt;em&gt;SelectionSet decodesTo2 scope&lt;/em&gt; and &lt;em&gt;SelectionSet decodesTo3 scope&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Note that the library &lt;em&gt;elm-graphql&lt;/em&gt; provides several &lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-SelectionSet#mapping-combining" rel="noopener noreferrer"&gt;mapN functions&lt;/a&gt; depending of the number of fields we want to map (&lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-SelectionSet#map" rel="noopener noreferrer"&gt;map&lt;/a&gt;, &lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-SelectionSet#map2" rel="noopener noreferrer"&gt;map2&lt;/a&gt;, ..., &lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-SelectionSet#map8" rel="noopener noreferrer"&gt;map8&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In our case, we want that the &lt;em&gt;decodesTo1&lt;/em&gt; becomes the type &lt;em&gt;String&lt;/em&gt;, &lt;em&gt;decodesTo2&lt;/em&gt; becomes &lt;em&gt;String&lt;/em&gt;, &lt;em&gt;decodesTo3&lt;/em&gt; becomes &lt;em&gt;Int&lt;/em&gt;, &lt;em&gt;decodesToCombined&lt;/em&gt; becomes &lt;em&gt;Image&lt;/em&gt; and &lt;em&gt;scope&lt;/em&gt; becomes &lt;em&gt;Imageboard.Object.Image&lt;/em&gt; to have this signature for the function &lt;em&gt;map3&lt;/em&gt; : &lt;em&gt;(String -&amp;gt; String -&amp;gt; Int -&amp;gt; Image) -&amp;gt; SelectionSet String Imageboard.Object.Image -&amp;gt; SelectionSet String Imageboard.Object.Image -&amp;gt; SelectionSet Int Imageboard.Object.Image -&amp;gt; SelectionSet Image Imageboard.Object.Image&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's important to notice that in Elm each type alias is a function&lt;/strong&gt;. This concept is called &lt;a href="https://guide.elm-lang.org/types/type_aliases#record-constructors" rel="noopener noreferrer"&gt;Record Constructors&lt;/a&gt;. Due to that, the type alias &lt;em&gt;Image&lt;/em&gt; is also a function with this signature &lt;em&gt;Image : String -&amp;gt; String -&amp;gt; Int -&amp;gt; Image&lt;/em&gt;. Also, remember that in Elm if we call a function without providing all the parameters, then the returned value is a function with the remaining parameters. For example, if we use the type &lt;em&gt;Image&lt;/em&gt; as a function and call it in this way &lt;code&gt;Image "PostGraphile"&lt;/code&gt;, the returned value is &lt;em&gt;String -&amp;gt; Int -&amp;gt; Image&lt;/em&gt;. If we call &lt;em&gt;Image&lt;/em&gt; like that &lt;code&gt;Image "PostgreSQL" "https://wiki.postgresql.org/images/a/a4/PostgreSQL_logo.3colors.svg"&lt;/code&gt;, the returned value is &lt;em&gt;Int -&amp;gt; Image&lt;/em&gt;. Finally, if we do &lt;code&gt;Image "PostgreSQL" "https://wiki.postgresql.org/images/a/a4/PostgreSQL_logo.3colors.svg" 1&lt;/code&gt;, the returned value is &lt;em&gt;Image&lt;/em&gt;. The last call of the type alias &lt;em&gt;Image&lt;/em&gt; is equivalent to this record &lt;code&gt;{ title = "PostgreSQL", url = "https://wiki.postgresql.org/images/a/a4/PostgreSQL_logo.3colors.svg", id = 1 }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is why we can call the function &lt;em&gt;map3&lt;/em&gt; like that: &lt;code&gt;map3 Image title url id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we go back to the function &lt;em&gt;allImages&lt;/em&gt;. For the first parameter of type &lt;em&gt;(AllImagesOptionalArguments -&amp;gt; AllImagesOptionalArguments)&lt;/em&gt;, we can use the &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/Basics#identity" rel="noopener noreferrer"&gt;identity function&lt;/a&gt;, that just returns the argument passed as parameter. For the second parameter of type &lt;em&gt;SelectionSet decodesTo Imageboard.Object.ImagesConnection&lt;/em&gt;, the decodesTo parameter value should be replaced by the type &lt;em&gt;Image&lt;/em&gt; to match the value returned by the expression &lt;em&gt;map3 Image title url id&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Note that the queries generated by PostGraphile often return an optional value. For this reason, the functions &lt;em&gt;nodes&lt;/em&gt; and &lt;em&gt;allImages&lt;/em&gt; return a &lt;em&gt;Maybe&lt;/em&gt; type. Due to that the returned type of the function &lt;em&gt;allImages&lt;/em&gt; is &lt;em&gt;SelectionSet (Maybe (List (Maybe Image))) RootQuery&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now the query function is like that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SelectionSet&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="kt"&gt;RootQuery&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;allImages&lt;/span&gt; &lt;span class="n"&gt;identity&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map3&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to add these import statements&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Operation&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;RootQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;SelectionSet&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SelectionSet&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ImagesConnection&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Query&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allImages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For making HTTP request to the GraphQL server, the function &lt;em&gt;send&lt;/em&gt; of the module &lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-Http" rel="noopener noreferrer"&gt;Graphql.Http&lt;/a&gt; can be used. The signature of this function is &lt;em&gt;(Result (Error decodesTo) decodesTo -&amp;gt; msg) -&amp;gt; Request decodesTo -&amp;gt; Cmd msg&lt;/em&gt;. The type variable &lt;em&gt;msg&lt;/em&gt; will be replaced by the custom type &lt;em&gt;Msg&lt;/em&gt; that we defined before. The type variable &lt;em&gt;decodesTo&lt;/em&gt; will be replaced by the type &lt;em&gt;Maybe (List (Maybe Image))&lt;/em&gt;. The same type that is returned by our function &lt;em&gt;query&lt;/em&gt;. Note that the type &lt;em&gt;Request&lt;/em&gt; is defined in the module &lt;em&gt;Graphql.Http&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The function &lt;em&gt;queryRequest&lt;/em&gt; of the module &lt;em&gt;Graphql.Http&lt;/em&gt; creates a value of type &lt;em&gt;Request&lt;/em&gt;. Its signature is &lt;em&gt;String -&amp;gt; SelectionSet decodesTo RootQuery -&amp;gt; Request decodesTo&lt;/em&gt;. The first parameter is the url of the GraphQL server and the second is a &lt;em&gt;SelectionSet&lt;/em&gt;. In our case, the second parameter will be the returned value of the call of our function &lt;em&gt;query&lt;/em&gt;, to have a value of type &lt;em&gt;SelectionSet (Maybe (List (Maybe Image))) RootQuery&lt;/em&gt; for the second parameter, and a returned value of type &lt;em&gt;Request (Maybe (List (Maybe Image)))&lt;/em&gt; for the function &lt;em&gt;queryRequest&lt;/em&gt;. A possible call of this function could be &lt;code&gt;queryRequest graphQLUrl query&lt;/code&gt; with &lt;em&gt;graphQLUrl&lt;/em&gt; a constant that contains a value of type String that represents the url of our GraphQL server (in our case it could be "&lt;a href="http://localhost:5000/graphql%22" rel="noopener noreferrer"&gt;http://localhost:5000/graphql"&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So, the result of the function &lt;em&gt;queryRequest&lt;/em&gt; could be passed to the second parameter of the function &lt;em&gt;send&lt;/em&gt;. For the first parameter, we can use the combination of the function &lt;em&gt;fromResult&lt;/em&gt; defined in the module &lt;a href="https://package.elm-lang.org/packages/krisajenkins/remotedata/latest/RemoteData" rel="noopener noreferrer"&gt;RemoteData&lt;/a&gt; (provided by the library &lt;em&gt;krisajenkins/remotedata&lt;/em&gt;) and the variant &lt;em&gt;GotResponse&lt;/em&gt; of the custom type &lt;em&gt;Msg&lt;/em&gt;. The function &lt;em&gt;send&lt;/em&gt; need for the first parameter a value of type &lt;em&gt;(Result (Error decodesTo) decodesTo -&amp;gt; msg)&lt;/em&gt;, with &lt;em&gt;decodesTo&lt;/em&gt; mapped to the type &lt;em&gt;Maybe (List (Maybe Image))&lt;/em&gt;, and &lt;em&gt;msg&lt;/em&gt; mapped to the type &lt;em&gt;Msg&lt;/em&gt;. Due to that, it need the type &lt;em&gt;(Result (Error (Maybe (List (Maybe Image)))) decodesTo -&amp;gt; Msg)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One important thing to understand is that the &lt;strong&gt;variant &lt;em&gt;GotResponse&lt;/em&gt; of the custom type &lt;em&gt;Msg&lt;/em&gt; is a function with this signature: Model -&amp;gt; Msg&lt;/strong&gt;. That's because each variant of a custom type is a function that returns the custom type himself. If this variant has some associated types, then the related function takes parameters of these types before returning the custom type.&lt;/p&gt;

&lt;p&gt;This is why &lt;em&gt;GotResponse&lt;/em&gt; is a function with the signature &lt;em&gt;Model -&amp;gt; Msg&lt;/em&gt;, but &lt;em&gt;Model&lt;/em&gt; is a type alias for &lt;em&gt;RemoteData (Error Response) Response&lt;/em&gt;. Due to the fact that &lt;em&gt;Response&lt;/em&gt; is a type alias for &lt;em&gt;Maybe (List (Maybe Image))&lt;/em&gt;, then &lt;em&gt;GotResponse&lt;/em&gt; has this signature: &lt;em&gt;RemoteData (Error (Maybe (List (Maybe Image)))) (Maybe (List (Maybe Image))) -&amp;gt; Msg&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;fromResult&lt;/em&gt; has this signature: &lt;em&gt;Result e a -&amp;gt; RemoteData e a&lt;/em&gt;, so in our case the signature becomes &lt;em&gt;Result (Error (Maybe (List (Maybe Image)))) (Maybe (List (Maybe Image))) -&amp;gt; RemoteData (Error (Maybe (List (Maybe Image)))) (Maybe (List (Maybe Image)))&lt;/em&gt;.&lt;br&gt;
In Elm, like in other functional programming language, we can use the &lt;a href="https://en.wikipedia.org/wiki/Function_composition_(computer_science)" rel="noopener noreferrer"&gt;function composition&lt;/a&gt; to create a new function from the two that we combined. The new function will take the parameters of the first function used and will return the same type of the second function used. In Elm, the operator &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/Basics#(%3E%3E)" rel="noopener noreferrer"&gt;&amp;gt;&amp;gt;&lt;/a&gt; is used to perform a function composition. Therefore, the result of the instruction &lt;code&gt;fromResult &amp;gt;&amp;gt; GotResponse&lt;/code&gt; is a function with this signature &lt;em&gt;Result (Error (Maybe (List (Maybe Image)))) (Maybe (List (Maybe Image))) -&amp;gt; Msg&lt;/em&gt;. And the following instruction &lt;code&gt;send (fromResult &amp;gt;&amp;gt; GotResponse) (queryRequest graphQLUrl query)&lt;/code&gt; returns a value of type &lt;em&gt;Cmd Msg&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We now have our final function &lt;em&gt;makeRequest&lt;/em&gt; with the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromResult&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;GotResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this module with the &lt;em&gt;import&lt;/em&gt; statement&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Http&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queryRequest&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the import of the module &lt;em&gt;RemoteData&lt;/em&gt; with the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import RemoteData exposing (RemoteData(..), fromResult)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can remove the &lt;em&gt;Error&lt;/em&gt; type defined when we created the Model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Remove this code because now we use the Error type defined in the module Graphql.Http&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;parsedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsedData&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the module &lt;a href=""&gt;elm/json&lt;/a&gt;, that is required by the code generated by &lt;em&gt;elm-graphql&lt;/em&gt;, and confirm the move to the direct dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;elm install elm/json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final source code of our Elm application is like that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Http&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queryRequest&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Operation&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;RootQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;SelectionSet&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SelectionSet&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ImagesConnection&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Query&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allImages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;RemoteData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fromResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Program&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Loading&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:5000/graphql"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromResult&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;GotResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SelectionSet&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="kt"&gt;RootQuery&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;allImages&lt;/span&gt; &lt;span class="n"&gt;identity&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map3&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;GotResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Sub&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Sub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;


&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;NotAsked&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Images are not yet asked."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Loading&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Images are loading..."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Failure&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There was a failure when we try to load the image."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No response could be retrieve from the server."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;div&lt;/span&gt;
                        &lt;span class="p"&gt;[]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Imageboard"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gallery"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;viewImage&lt;/span&gt; &lt;span class="n"&gt;maybeImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;maybeImage&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No data could be retrieved from the server."&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;img&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[]&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;GotResponse&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we did before, run again this command &lt;code&gt;elm make src/Main.elm --output=main.js&lt;/code&gt; to regenerate the JavaScript file.&lt;br&gt;
Open the file &lt;code&gt;index.html&lt;/code&gt; with your web browser and check that all the images inserted in the PostgreSQL database are well displayed ✨.&lt;/p&gt;

&lt;p&gt;If you have some troubles, verify that the GraphQL server generated by &lt;em&gt;PostGraphile&lt;/em&gt; is still running. If needed, execute again the command &lt;code&gt;postgraphile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that to avoid cors issue, you must add the &lt;code&gt;--cors&lt;/code&gt; option when running the command &lt;code&gt;postgraphile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The reason is explained in the &lt;a href="https://postgraphile.org/postgraphile/4/plugins/#origin-specific-cors" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;. It's possible to avoid using unrestricted CORS settings by using PostGraphile as a library, inside a Node.js program that will serve our static files.&lt;/p&gt;
&lt;h4&gt;
  
  
  Bonus: some syntactic sugars
&lt;/h4&gt;

&lt;p&gt;If you look on some examples of the &lt;a href="https://github.com/dillonkearns/elm-graphql/tree/master/examples" rel="noopener noreferrer"&gt;elm-graphql documentation&lt;/a&gt;, you can notice that the operator &lt;code&gt;|&amp;gt;&lt;/code&gt; is used when making the GraphQL query.&lt;br&gt;
You can find more information about this operator in the &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/Basics#(|%3E)" rel="noopener noreferrer"&gt;Elm documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Basically, instead of doing these instructions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromResult&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;GotResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we can do that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;queryRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromResult&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;GotResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way to write the code is named the &lt;em&gt;pipeline syntax&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Also, it's possible to use the keyword &lt;em&gt;as&lt;/em&gt; when importing a module to have an alias name for this module. This is useful to quickly see that a given function comes from the library &lt;em&gt;elm-graphql&lt;/em&gt;. Also, we don't need to import the function that we use during the import section.&lt;/p&gt;

&lt;p&gt;Basically, the new source code of the functions &lt;em&gt;makeRequest&lt;/em&gt; and &lt;em&gt;query&lt;/em&gt; are&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;makeRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;queryRequest&lt;/span&gt; &lt;span class="n"&gt;graphQLUrl&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromResult&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;GotResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SelectionSet&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="kt"&gt;RootQuery&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allImages&lt;/span&gt; &lt;span class="n"&gt;identity&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ImagesConnection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SelectionSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map3&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the import statements become&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Only the import statements modified are shown&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Http&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;SelectionSet&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;SelectionSet&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SelectionSet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Image&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ImagesConnection&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;ImagesConnection&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Imageboard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Query&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Query&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You learn how to use PostgreSQL, GraphQL, PostGraphile, Elm and elm-graphql for creating a simple imageboard.&lt;/p&gt;

&lt;p&gt;The source code is available in this &lt;a href="https://github.com/kaizar36/imageboard" rel="noopener noreferrer"&gt;git repository&lt;/a&gt; with some enhancements.&lt;/p&gt;

&lt;p&gt;You can make some improvements in your side, if you want. For example by using GraphQL mutation inside our Elm application for adding an image, or by combining elm-graphql, PostGraphile and &lt;a href="https://package.elm-lang.org/packages/jschomay/elm-paginate/latest" rel="noopener noreferrer"&gt;elm-paginate&lt;/a&gt; to manage the pagination.&lt;/p&gt;

&lt;p&gt;If you want to go deeper, you can check the following links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/" rel="noopener noreferrer"&gt;PostgreSQL documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.graphile.org/postgraphile/" rel="noopener noreferrer"&gt;PostGraphile documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://graphql.org/learn/" rel="noopener noreferrer"&gt;GraphQL documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elm-lang.org/docs" rel="noopener noreferrer"&gt;Elm documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/" rel="noopener noreferrer"&gt;elm-graphql documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elm</category>
      <category>graphql</category>
      <category>postgres</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
