<?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: jjoo</title>
    <description>The latest articles on DEV Community by jjoo (@version1).</description>
    <link>https://dev.to/version1</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F487075%2F2abe4cad-7a7e-40df-98c6-0fd9d8b001a6.png</url>
      <title>DEV Community: jjoo</title>
      <link>https://dev.to/version1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/version1"/>
    <language>en</language>
    <item>
      <title>Controlling Codex via JSON-RPC with Codex App Server</title>
      <dc:creator>jjoo</dc:creator>
      <pubDate>Mon, 20 Jul 2026 01:07:46 +0000</pubDate>
      <link>https://dev.to/version1/controlling-codex-via-json-rpc-with-codex-app-server-1moc</link>
      <guid>https://dev.to/version1/controlling-codex-via-json-rpc-with-codex-app-server-1moc</guid>
      <description>&lt;p&gt;Have you heard of Codex App Server?&lt;/p&gt;

&lt;p&gt;Instead of interacting with Codex through the CLI, Codex App Server lets you control a Codex agent over JSON-RPC.&lt;/p&gt;

&lt;p&gt;In other words, you can build your own GUI, TUI, task queue, or orchestration layer on top of Codex.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This article focuses on keeping a fast pace, so if you're looking for precise protocol details and specifications, please refer to the official README:&lt;br&gt;
&lt;a href="https://github.com/openai/codex/blob/main/codex-rs/app-server/README.md" rel="noopener noreferrer"&gt;https://github.com/openai/codex/blob/main/codex-rs/app-server/README.md&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Starting Codex App Server is as simple as running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex app-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;The server will begin listening on standard input. From there, you simply send JSON requests that follow the protocol (technically JSONL, so each request must be on a single line).&lt;/p&gt;

&lt;p&gt;This allows your own applications to launch and control Codex agents programmatically through Codex App Server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conversation Flow
&lt;/h2&gt;

&lt;p&gt;A typical interaction looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send an initialize request to initialize the server.&lt;/li&gt;
&lt;li&gt;Start an agent conversation with &lt;code&gt;thread/start&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Give the agent work using &lt;code&gt;turn/start&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Wait until you receive &lt;code&gt;turn/completed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Repeat steps 3–4 until the task is finished.&lt;/li&gt;
&lt;li&gt;Done.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding Thread and Turn
&lt;/h2&gt;

&lt;p&gt;When I first started learning the protocol, I found it difficult to picture the relationship between Thread and Turn.&lt;/p&gt;

&lt;p&gt;The following example helped everything click:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread
├── Turn 1
│   User:
│     "Please investigate this issue."
│
│   Agent:
│     - Search the codebase
│     - Read relevant files
│     - Identify the root cause
│
│   turn/completed
│
├── Turn 2
│   User:
│     "Please fix it."
│
│   Agent:
│     - Edit files
│     - Run tests
│
│   turn/completed
│
├── Turn 3
│   User:
│     "Create a pull request."
│
│   Agent:
│     - Commit changes
│     - Push to Git
│     - Create a PR
│
│   turn/completed
│
└── End of Thread
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;Thread&lt;/code&gt; is roughly equivalent to a Codex CLI session, while a &lt;code&gt;Turn&lt;/code&gt; represents a single exchange between the user and the agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hands-on
&lt;/h2&gt;

&lt;p&gt;By default, Codex App Server accepts JSON-RPC messages through standard input.&lt;/p&gt;

&lt;p&gt;If you copy and paste the following JSON into a running server (after converting it into a single-line JSONL message), you'll be able to interact with a persistent Codex agent.&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"initialize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&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;"clientInfo"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tutorial"&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;"Tutorial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&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;After sending it, you'll receive a response similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% codex app-server
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;:1,&lt;span class="s2"&gt;"method"&lt;/span&gt;:&lt;span class="s2"&gt;"initialize"&lt;/span&gt;,&lt;span class="s2"&gt;"params"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"clientInfo"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"tutorial"&lt;/span&gt;,&lt;span class="s2"&gt;"title"&lt;/span&gt;:&lt;span class="s2"&gt;"Tutorial"&lt;/span&gt;,&lt;span class="s2"&gt;"version"&lt;/span&gt;:&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="o"&gt;}}}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;:1,&lt;span class="s2"&gt;"result"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"userAgent"&lt;/span&gt;:&lt;span class="s2"&gt;"tutorial/0.144.5 (Mac OS 26.5.0; arm64) xterm-256color (tutorial; 1.0)"&lt;/span&gt;,&lt;span class="s2"&gt;"codexHome"&lt;/span&gt;:&lt;span class="s2"&gt;"~/.codex"&lt;/span&gt;,&lt;span class="s2"&gt;"platformFamily"&lt;/span&gt;:&lt;span class="s2"&gt;"unix"&lt;/span&gt;,&lt;span class="s2"&gt;"platformOs"&lt;/span&gt;:&lt;span class="s2"&gt;"macos"&lt;/span&gt;&lt;span class="o"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"method"&lt;/span&gt;:&lt;span class="s2"&gt;"remoteControl/status/changed"&lt;/span&gt;,&lt;span class="s2"&gt;"params"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;:&lt;span class="s2"&gt;"disabled"&lt;/span&gt;,&lt;span class="s2"&gt;"serverName"&lt;/span&gt;:&lt;span class="s2"&gt;"xxx.local"&lt;/span&gt;,&lt;span class="s2"&gt;"installationId"&lt;/span&gt;:&lt;span class="s2"&gt;"2124e102-01b2-4b60-94c3-dabb22d2913f"&lt;/span&gt;,&lt;span class="s2"&gt;"environmentId"&lt;/span&gt;:null&lt;span class="o"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the server has been successfully initialized.&lt;/p&gt;

&lt;p&gt;Next, start a conversation with an agent by sending a thread/start request:&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="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"thread/start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"params"&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;The response will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"id":2,"result":{"thread":{"id":"019f7960-95a5-7140-8749-a3cf59e0ffab","extra":null,"sessionId":"019f7960-95a5-7140-8749-a3cf59e0ffab","forkedFromId":null,"parentThreadId":null,"preview":"","ephemeral":false,"historyMode":"legacy","modelProvider":"openai","createdAt":1784447800,"updatedAt":1784447800,"recencyAt":1784447800, ...}
{"method":"thread/started","params":{"thread":{"id":"019f7960-95a5-7140-8749-a3cf59e0ffab","extra":null,"sessionId":"019f7960-95a5-7140-8749-a3cf59e0ffab", ...}
{"method":"mcpServer/startupStatus/updated","params":{"threadId":"019f7960-95a5-7140-8749-a3cf59e0ffab","name":"codex_apps","status":"starting","error":null,"failureReason":null}}
{"method":"mcpServer/startupStatus/updated","params":{"threadId":"019f7960-95a5-7140-8749-a3cf59e0ffab","name":"context7","status":"starting","error":null,"failureReason":null}}
{"method":"mcpServer/startupStatus/updated","params":{"threadId":"019f7960-95a5-7140-8749-a3cf59e0ffab","name":"notion-mcp-server","status":"starting","error":null,"failureReason":null}}
{"method":"mcpServer/startupStatus/updated","params":{"threadId":"019f7960-95a5-7140-8749-a3cf59e0ffab","name":"notion-mcp-server","status":"ready","error":null,"failureReason":null}}
{"method":"mcpServer/startupStatus/updated","params":{"threadId":"019f7960-95a5-7140-8749-a3cf59e0ffab","name":"codex_apps","status":"ready","error":null,"failureReason":null}}
{"method":"mcpServer/startupStatus/updated","params":{"threadId":"019f7960-95a5-7140-8749-a3cf59e0ffab","name":"context7","status":"ready","error":null,"failureReason":null}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output may look a little noisy, but you'll notice events such as thread/started, followed by the startup of MCP servers.&lt;/p&gt;

&lt;p&gt;If you've used the codex command before, this should feel very familiar—the same initialization process is happening behind the scenes.&lt;/p&gt;

&lt;p&gt;Next, let's send a task to the agent using &lt;code&gt;turn/start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For this example, we'll ask it to introduce itself with the following prompt:&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="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"turn/start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"threadId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"019f7960-95a5-7140-8749-a3cf59e0ffab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"input"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Hello! Please introduce yourself."&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;The response is quite long, so I'll omit most of it here. The message worth paying attention to is this one:&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;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"item/completed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&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;"item"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agentMessage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"msg_0e30b319d2fc7416016a5c854b85a0819192efde569032bd15"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello! I'm Codex.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;I can help with code investigation, implementation, testing, code reviews, Git operations, pull request preparation, and more within this workspace. My general approach is to understand the existing architecture and repository conventions before making small, safe changes.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;For this repository, I'll follow your instructions and respond primarily in Japanese."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"phase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"final_answer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"memoryCitation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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;"threadId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"019f7960-95a5-7140-8749-a3cf59e0ffab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"turnId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"019f7968-a116-7f13-bf24-c56fddd4373d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"completedAtMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1784448333474&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;The response is divided into several types of events.&lt;/p&gt;

&lt;p&gt;The most important one is &lt;code&gt;item/agentMessage/delta&lt;/code&gt;, which streams the agent's response in small chunks as it is generated. Once the response is complete, the full message is available in the &lt;code&gt;item/completed&lt;/code&gt; event.&lt;/p&gt;

&lt;p&gt;At this point, you've seen the complete interaction flow. From here on, you simply continue sending &lt;code&gt;turn/start&lt;/code&gt; requests to assign new tasks. By repeating this process until all work is finished, you can drive the agent through an entire workflow programmatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Codex App Server?
&lt;/h2&gt;

&lt;p&gt;When working with Codex day to day, you typically launch the interactive console with the &lt;code&gt;codex&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;However, if you keep a Codex App Server running locally and send JSONL requests to it instead, you unlock a number of interesting possibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run Codex agents in headless mode.&lt;/li&gt;
&lt;li&gt;Send tasks directly to the App Server without opening a new &lt;code&gt;codex&lt;/code&gt; session and manually entering prompts for each task.&lt;/li&gt;
&lt;li&gt;Build your own custom clients, such as GUIs, TUIs, or web applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenAI has also introduced Codex Symphony](&lt;a href="https://openai.com/ja-JP/index/open-source-codex-orchestration-symphony/" rel="noopener noreferrer"&gt;https://openai.com/ja-JP/index/open-source-codex-orchestration-symphony/&lt;/a&gt;), a specification for orchestrating multiple coding agents. Building your own orchestration layer on top of Codex App Server would be an interesting project.&lt;/p&gt;

&lt;p&gt;Since Codex App Server continuously emits events that reflect the agent's state, you can also monitor its progress in real time. This opens the door to building tools similar to &lt;strong&gt;Herdr&lt;/strong&gt;, with features for tracking and visualizing the state of long-running agent workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tasq: An Open-Source Project I Built
&lt;/h2&gt;

&lt;p&gt;As a bit of self-promotion, I'd also like to introduce &lt;strong&gt;Tasq&lt;/strong&gt;, an open-source project I built on top of Codex App Server.&lt;/p&gt;

&lt;p&gt;If you're curious about how it works, I recommend checking out the demo video in the README—it gives a good sense of the overall workflow and user experience.&lt;/p&gt;

&lt;p&gt;Tasq is built around local issue management. Once you add implementation plans created by tools like Claude Code or Codex to your backlog, Tasq can automatically drive coding agents through the entire workflow—from implementation all the way to creating a pull request.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/version-1/tasq" rel="noopener noreferrer"&gt;https://github.com/version-1/tasq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/version1/introducing-tasq-an-ai-native-task-orchestrator-for-coding-agents-506c"&gt;https://dev.to/version1/introducing-tasq-an-ai-native-task-orchestrator-for-coding-agents-506c&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;If Tasq sounds interesting, I'd love for you to give it a try. Feedback, issues, and contributions are always welcome.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>programming</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Queue Your Plan. Get PRs. — Tasq, a Task Queue for Coding Agents</title>
      <dc:creator>jjoo</dc:creator>
      <pubDate>Tue, 14 Jul 2026 04:45:34 +0000</pubDate>
      <link>https://dev.to/version1/introducing-tasq-an-ai-native-task-orchestrator-for-coding-agents-506c</link>
      <guid>https://dev.to/version1/introducing-tasq-an-ai-native-task-orchestrator-for-coding-agents-506c</guid>
      <description>&lt;p&gt;If you'd rather try it first than read about it, there's a demo video and a quick tutorial that walk you through the entire workflow in just a few minutes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/version-1/tasq#tasq" rel="noopener noreferrer"&gt;Demo Movie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://version-1.github.io/tasq/getting-started/agent-tutorial" rel="noopener noreferrer"&gt;Tasq | Agent Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end of it, you'll have an agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;picking up issues automatically&lt;/li&gt;
&lt;li&gt;implementing changes in isolated worktrees&lt;/li&gt;
&lt;li&gt;creating pull requests&lt;/li&gt;
&lt;li&gt;updating issue states as work progresses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article explains why I built tasq and the problems it tries to solve.&lt;/p&gt;




&lt;p&gt;I spend most of my time building software with AI coding agents.&lt;/p&gt;

&lt;p&gt;My workflow usually looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Claude Code and custom skills to explore a problem and generate a plan.&lt;/li&gt;
&lt;li&gt;Ask Codex to implement the plan.&lt;/li&gt;
&lt;li&gt;Let the agent create a pull request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first, it felt magical.&lt;/p&gt;

&lt;p&gt;Then I started running multiple agents in parallel.&lt;/p&gt;

&lt;p&gt;While one agent was investigating a bug, another was implementing a feature. While waiting for CI to finish, I would ask yet another agent to work on a different task.&lt;/p&gt;

&lt;p&gt;A few days later I noticed a problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tasks are currently running?&lt;/li&gt;
&lt;li&gt;Which tasks are blocked by dependencies?&lt;/li&gt;
&lt;li&gt;Which tasks are already finished?&lt;/li&gt;
&lt;li&gt;Which conversation thread belongs to which implementation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes an agent would finish a task and I wouldn't notice for days.&lt;/p&gt;

&lt;p&gt;Sometimes I would discover an unfinished implementation a week later and wonder why it had stopped in the first place.&lt;/p&gt;

&lt;p&gt;AI made software development massively parallel.&lt;/p&gt;

&lt;p&gt;But my task management workflow was still designed for humans.&lt;/p&gt;

&lt;p&gt;That's why I built &lt;strong&gt;tasq&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/version-1" rel="noopener noreferrer"&gt;
        version-1
      &lt;/a&gt; / &lt;a href="https://github.com/version-1/tasq" rel="noopener noreferrer"&gt;
        tasq
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AI-native task orchestrator for coding agents 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;tasq&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;AI coding agent task manager.&lt;/p&gt;
&lt;p&gt;tasq helps you turn implementation work into a visible queue, start local services for that queue, and inspect progress from both the &lt;code&gt;tq&lt;/code&gt; CLI and the Web UI.&lt;/p&gt;

  
    
    &lt;span class="m-1"&gt;intro_v2.mp4&lt;/span&gt;
  

  

  


&lt;p&gt;&lt;a href="https://github.com/user-attachments/assets/8c4fdc9c-c70b-4f86-8e0a-323f8880ffb7" rel="noopener noreferrer"&gt;Watch the Tasq introduction video&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Japanese counterpart: &lt;a href="https://github.com/version-1/tasq/README.ja.md" rel="noopener noreferrer"&gt;README.ja.md&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Problem&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;AI coding agents make it possible to work on multiple implementation tasks at the same time. The bottleneck moves from writing code to managing parallel work.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Human Context Switching&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Agents can run in parallel, but humans still need to track which tasks were assigned, which agents are running, how far each task has progressed, and what should be reviewed next.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Workspace Conflicts&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Running multiple agents in one repository checkout can create branch switching issues, unfinished-change conflicts, and overlapping file edits.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Repeated Setup Work&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Each agent task often needs the same preparation steps: create a branch, create a worktree, verify dependencies, and run the right…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/version-1/tasq" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;An AI-native task orchestrator designed for coding agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not GitHub Issues or Linear?
&lt;/h2&gt;

&lt;p&gt;The obvious answer is to create more issues.&lt;/p&gt;

&lt;p&gt;The problem is that not all tasks belong in a shared project management system.&lt;/p&gt;

&lt;p&gt;I don't want to publish every tiny implementation detail, development experiment, or dotfiles improvement to a team-wide Linear workspace.&lt;/p&gt;

&lt;p&gt;Many of these tasks are personal implementation notes or intermediate steps that only exist to help me finish larger work.&lt;/p&gt;

&lt;p&gt;They also have dependencies.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create database schema&lt;/li&gt;
&lt;li&gt;Implement repository layer&lt;/li&gt;
&lt;li&gt;Add API endpoints&lt;/li&gt;
&lt;li&gt;Update frontend integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't want to manually copy and paste these tasks into agents in the correct order.&lt;/p&gt;

&lt;p&gt;I want the system to understand the dependency graph and schedule the work automatically.&lt;/p&gt;

&lt;p&gt;What I needed was:&lt;/p&gt;

&lt;p&gt;Run multiple agents and automatically consume tasks while respecting dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is tasq?
&lt;/h2&gt;

&lt;p&gt;tasq combines three ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A local issue tracker&lt;/li&gt;
&lt;li&gt;A dependency-aware task queue&lt;/li&gt;
&lt;li&gt;An orchestrator for coding agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Issues are stored locally in a database rather than in GitHub or Linear.&lt;/p&gt;

&lt;p&gt;The orchestrator continuously watches the queue and dispatches executable tasks to coding agents.&lt;/p&gt;

&lt;p&gt;Each task runs in its own Git worktree and branch, so multiple implementations can happen in parallel without conflicts.&lt;/p&gt;

&lt;p&gt;tasq was heavily inspired by Codex Symphony and its orchestration model, while focusing on local-first and personal workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflow Customization
&lt;/h2&gt;

&lt;p&gt;The default implementation loop looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a worktree and branch.&lt;/li&gt;
&lt;li&gt;Move the issue to &lt;code&gt;in_progress&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Implement the requested changes.&lt;/li&gt;
&lt;li&gt;Run agent-based review.&lt;/li&gt;
&lt;li&gt;Create a pull request.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, these steps are not hardcoded.&lt;/p&gt;

&lt;p&gt;tasq uses &lt;code&gt;WORKFLOW.md&lt;/code&gt; files inspired by Symphony's workflow specification.&lt;/p&gt;

&lt;p&gt;This means users can customize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;review strategies&lt;/li&gt;
&lt;li&gt;branching models&lt;/li&gt;
&lt;li&gt;required checks&lt;/li&gt;
&lt;li&gt;skill selection&lt;/li&gt;
&lt;li&gt;pull request behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;tasq only cares about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;issue dependencies&lt;/li&gt;
&lt;li&gt;issue states&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else belongs to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autonomous agents still need humans
&lt;/h2&gt;

&lt;p&gt;In an ideal world, agents would continuously fetch tasks and finish them without interruption.&lt;/p&gt;

&lt;p&gt;Reality is messier.&lt;/p&gt;

&lt;p&gt;Agents may require permissions.&lt;/p&gt;

&lt;p&gt;CI pipelines fail.&lt;/p&gt;

&lt;p&gt;Implementations sometimes diverge from expectations.&lt;/p&gt;

&lt;p&gt;For these situations, tasq intentionally stays lightweight.&lt;/p&gt;

&lt;p&gt;Each issue stores the execution session identifier of the underlying coding agent.&lt;/p&gt;

&lt;p&gt;If something goes wrong, you can simply continue from the existing session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex resume &amp;lt;thread_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't need to create another issue just to fix CI failures or tweak a generated implementation.&lt;/p&gt;

&lt;p&gt;You simply resume the conversation and continue from where the agent stopped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typical Workflow
&lt;/h2&gt;

&lt;p&gt;A typical tasq workflow looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a plan using Claude Code, Codex, or your preferred tools.&lt;/li&gt;
&lt;li&gt;Convert the plan into issues with &lt;code&gt;tq issue create&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Review the generated issues and mark them as &lt;code&gt;ready&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Let the orchestrator dispatch work automatically.&lt;/li&gt;
&lt;li&gt;Review the generated pull requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, this often means your work becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Review issues and move them to ready.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everything else happens automatically.&lt;/p&gt;

&lt;p&gt;tasq provides both a web interface and a CLI interface.&lt;/p&gt;

&lt;p&gt;The CLI is primarily intended for coding agents, while the web interface focuses on issue management and orchestration visibility.&lt;/p&gt;

&lt;p&gt;There is also a dedicated tasq skill package for coding agents so they can interact with the issue tracker without additional prompting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;There is still a lot to improve.&lt;/p&gt;

&lt;p&gt;Current ideas include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TUI support&lt;/li&gt;
&lt;li&gt;Seamless recovery of blocked tasks&lt;/li&gt;
&lt;li&gt;Better onboarding and startup configuration&lt;/li&gt;
&lt;li&gt;Claude Code integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I personally spend most of my time inside tmux and Vim, so a TUI feels inevitable.&lt;/p&gt;

&lt;p&gt;I also want blocked tasks to recover automatically whenever possible.&lt;/p&gt;

&lt;p&gt;For example, if CI fails, users shouldn't need to manually resume an agent and type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;fix ci&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, tasq currently depends on Codex App Server and does not yet support direct execution through Claude Code.&lt;/p&gt;

&lt;p&gt;Long term, I would like planning and implementation workflows to work seamlessly across both ecosystems.&lt;/p&gt;

&lt;p&gt;If any of this sounds interesting, I'd love for you to try the tutorial and share your feedback.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://version-1.github.io/tasq/" rel="noopener noreferrer"&gt;Tasq Document Site&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Implementing Ruby's methods Method in JavaScript</title>
      <dc:creator>jjoo</dc:creator>
      <pubDate>Tue, 30 Jul 2024 10:40:43 +0000</pubDate>
      <link>https://dev.to/version1/implementing-rubys-methods-method-in-javascript-p1e</link>
      <guid>https://dev.to/version1/implementing-rubys-methods-method-in-javascript-p1e</guid>
      <description>&lt;p&gt;Suddenly, isn't Ruby's methods method handy? When writing code, it lists all the methods and properties available for an object and allows you to search through them, which is very useful for debugging.&lt;/p&gt;

&lt;p&gt;Besides that, it is also effective for checking methods specific to frameworks like Rails, aiding in code reading and understanding libraries. While it's good practice to refer to official documentation or source code, the methods method is quite helpful for libraries where you don’t need to dive deeply or when you have vague memories of method names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ruby's &lt;code&gt;methods&lt;/code&gt; Method
&lt;/h2&gt;

&lt;p&gt;To briefly introduce Ruby's methods method, it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ruby-doc.org/3.2.2/Object.html#method-i-methods" rel="noopener noreferrer"&gt;Object#method&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Returns a list of the names of public and protected methods of obj. This will include all the methods accessible in obj’s ancestors. If the optional parameter is false, it returns an array of obj’s public and protected singleton methods, the array will not include methods in modules included in obj.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, it returns an array object of the properties and methods accessible from the receiver.&lt;/p&gt;

&lt;p&gt;This method is implemented in the Object class, which is the ancestor of all classes that inherit from Object, so it can be used in any class inheriting from Object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Code&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hoge&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:fuga&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Hoge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;methods&lt;/span&gt;     &lt;span class="sr"&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="ss"&gt;:bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fuga&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fuga&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:singleton_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:dup&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="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Hoge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grep&lt;/span&gt; &lt;span class="sr"&gt;/fuga/&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="sr"&gt;/ =&amp;gt; [:fuga=, :fuga]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As shown in the example, it returns an Array object, so you can also search through the list of methods using the grep method, which is very convenient.&lt;/p&gt;

&lt;p&gt;So, I thought about whether this could be done in JS and gave it a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Below is the actual code.&lt;/p&gt;

&lt;p&gt;The class name can be anything, but I’m naming it PropertyFinder for now.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PropertyFinder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;grep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regexp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;regexp&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regexp&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regexp&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOwnPropertyNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__proto__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ancestors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PropertyFinder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__proto__&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;ancestors&lt;/span&gt;&lt;span class="p"&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;I’ll explain the code later, but let’s start with how to use it.&lt;/p&gt;

&lt;p&gt;Once the class is defined, you can add a method to the Object class's properties as follows:&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PropertyFinder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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;By doing this, you can use the methods method on instances of classes inheriting from Object. However, please be aware of the caution note below and use this at your own risk.&lt;/p&gt;

&lt;p&gt;Here are some example executions:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hoge&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;fuga&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fuga&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; ['constructor', 'constructor', '__defineGetter__', '__defineSetter__', 'hasOwnProperty' ...]&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;([].&lt;/span&gt;&lt;span class="nf"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;           &lt;span class="c1"&gt;// =&amp;gt; ['length', 'length', 'constructor', 'at', 'concat', ...]&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Hoge&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;grep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/fuga/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// =&amp;gt; ['fuga']&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Safety Introduction
&lt;/h2&gt;

&lt;p&gt;*&lt;em&gt;This code is not recommended for use in production environments *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Adding properties to higher-level classes through monkey-patching is an anti-pattern and could lead to problems with future changes in JS specifications. Use it with caution and at your own risk.&lt;/p&gt;

&lt;p&gt;Reference : &lt;a href="https://www.audero.it/blog/2016/12/05/monkey-patching-javascript/#the-cons-of-monkey-patching" rel="noopener noreferrer"&gt;The cons of monkey patching&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Explanation
&lt;/h2&gt;

&lt;p&gt;Now, let's move on to explaining the code.&lt;/p&gt;

&lt;p&gt;The most important method in PropertyFinder is the find method. This method traverses the prototype chain of the given object, searches for accessible properties, and returns them as a list.&lt;/p&gt;

&lt;p&gt;The toString and grep methods simply use find, so they don't need further explanation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prototype Chain
&lt;/h3&gt;

&lt;p&gt;The prototype chain might be unfamiliar to some, but it’s the inheritance of properties from the Object class.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain" rel="noopener noreferrer"&gt;Inheritance and the prototype chain | MDN &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The details are covered in the MDN documentation, but JavaScript's inheritance mechanism is supported by the prototype chain.&lt;/p&gt;

&lt;p&gt;Although it's not always obvious, when referring to some property, the process involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checking if the receiver itself has the property.&lt;/li&gt;
&lt;li&gt;Checking if the parent class instance has the property.&lt;/li&gt;
&lt;li&gt;Checking if the property exists in the parent class’s instance's parent class.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process continues up the chain until a match is found, which is then returned.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the &lt;code&gt;find&lt;/code&gt; Method Does
&lt;/h3&gt;

&lt;p&gt;Given the above, the find method in PropertyFinder implements this mechanism, allowing you to get a list of properties by recursively exploring &lt;code&gt;__proto__&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the implementation that achieves this by exploring &lt;code&gt;__proto__&lt;/code&gt; recursively to get the list:&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOwnPropertyNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__proto__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ancestors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PropertyFinder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__proto__&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;ancestors&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;That concludes the explanation of PropertyFinder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;That wraps up the explanation of the code and what I’ve tried.&lt;/p&gt;

&lt;p&gt;This was more of an experimental or playful exercise, but since it involved some knowledge and techniques, I hope you find it useful or inspiring for your own applications.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Tried to Create Crud API Gin+Gorm+GraphQL(gqlgen)</title>
      <dc:creator>jjoo</dc:creator>
      <pubDate>Sat, 02 Jan 2021 01:46:59 +0000</pubDate>
      <link>https://dev.to/version1/tried-to-create-crud-api-gin-gorm-graphql-gqlgen-16cg</link>
      <guid>https://dev.to/version1/tried-to-create-crud-api-gin-gorm-graphql-gqlgen-16cg</guid>
      <description>&lt;p&gt;I usually develop backend with Ruby on Rails so I'm not familier with golang but I have studied it and created a GraphQL API with Gin + Gorm + GraphQL.&lt;/p&gt;

&lt;p&gt;I will explain about entire flow. Next, I will talk about stack point I was working in.&lt;/p&gt;

&lt;p&gt;This is the repository.&lt;br&gt;
&lt;a href="https://github.com/version-1/gin-gorm-gqlgen-sample" rel="noopener noreferrer"&gt;gin-gorm-gqlgen-sample&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Technologies I used
&lt;/h2&gt;

&lt;p&gt;Followings are technologies I used this time,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Dep (package manager)&lt;/li&gt;
&lt;li&gt;Gin (WAF)&lt;/li&gt;
&lt;li&gt;Gorm (ORM)&lt;/li&gt;
&lt;li&gt;gqlgen (GraphQL Library)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Gin
&lt;/h4&gt;

&lt;p&gt;Gin is one of the Go language WAF. It have got the most star on github in go lang WAF(as far as I know).&lt;/p&gt;
&lt;h4&gt;
  
  
  Gorm
&lt;/h4&gt;

&lt;p&gt;Gorm is Go Lang ORM. According to web articles, its interface is like Rails's ActiveRecord.&lt;br&gt;
I am familliar with Rails so I choose this library.&lt;/p&gt;
&lt;h4&gt;
  
  
  Dep
&lt;/h4&gt;

&lt;p&gt;Dep is pacakge manager. I need to "go get" to install some libraries but it seems like disturbing my Dockerfile.&lt;br&gt;
So I used dep&lt;/p&gt;
&lt;h4&gt;
  
  
  gqlgen
&lt;/h4&gt;

&lt;p&gt;gqlgen is GraphQL server library. There are some graphql libraries for golang such as &lt;a href="https://github.com/graphql-go/graphql" rel="noopener noreferrer"&gt;graphql-go/graphql&lt;/a&gt;.&lt;br&gt;
But I selected gqlgen becuase I really like a point of generating code after I defined schema.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/99designs/gqlgen" rel="noopener noreferrer"&gt;99designs/gqlgen&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you use gqlgen, you can proceed your development with following procedure.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define Schema&lt;/li&gt;
&lt;li&gt;Write logic about query in resolvers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this process, you can focus on writing logic and you don't need to write boring code because gqlgen genearate code based on your schema.&lt;/p&gt;
&lt;h2&gt;
  
  
  Entire Flow
&lt;/h2&gt;

&lt;p&gt;The gqlgen sample in the document is baout Todo List. If you will read "Getting Start", you start it easily.&lt;br&gt;
But, I need to do something when you use it with Gorm or you develop CRUD. So, I will explain those way, So, I will explain those way.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install gqlgen with dep
&lt;/h3&gt;

&lt;p&gt;You can install gqlgen by "go get" but if you use dep, you have to prepare wrapper scripts to generate boilerplate.&lt;/p&gt;

&lt;p&gt;scripts/gqlgen.go&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/99designs/gqlgen/cmd"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&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;If you do this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$go&lt;/span&gt; run scripts/gqlgen.go init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will be able to execute it like this.&lt;br&gt;
When you finished to write scripts, make files you need on gqlgen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$go&lt;/span&gt; run scripts/gqlgen.go init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gqlgen will generate followings files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gqlgen.yml ・・・ Configure file. you write the configure fo generated code.&lt;/li&gt;
&lt;li&gt;genereated.go ・・・ When you define schema and execute scripts, this file will be generatted. Must not edit manually because it is generated.&lt;/li&gt;
&lt;li&gt;models_gen.go ・・・ This file is also generated from schema. Must not edit manually because it is generated.&lt;/li&gt;
&lt;li&gt;resolver.go ・・・ This is generated if you yet to create this name file.&lt;/li&gt;
&lt;li&gt;server/server.go ・・・ Entrypoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;When you generate code, excecute following command and install pacakges.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dep ensure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Entry Point for Gin
&lt;/h3&gt;

&lt;p&gt;I have to prepare entry point for gin if you want to use gin.&lt;br&gt;
prepare two endpoints.( for playground and main)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s"&gt;"github.com/99designs/gqlgen/handler"&lt;/span&gt;
  &lt;span class="s"&gt;"github.com/gin-gonic/gin"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Defining the Graphql handler&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;graphqlHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandlerFunc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraphQL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NewExecutableSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Resolvers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Resolver&lt;/span&gt;&lt;span class="p"&gt;{}}))&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Writer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Defining the Playground handler&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;playgroundHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandlerFunc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Playground&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GraphQL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/query"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Writer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;// Setting up Gin&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;graphqlHandler&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;playgroundHandler&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&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;h3&gt;
  
  
  Prepare Gorm Model
&lt;/h3&gt;

&lt;p&gt;Next, I will define model which are used on schema definition.&lt;br&gt;
I put it on internal/models according to go language standard layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// user.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;        &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Todos&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;
    &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
    &lt;span class="n"&gt;UpdatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// todo.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;        &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;Text&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Done&lt;/span&gt;      &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;UserID&lt;/span&gt;    &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;User&lt;/span&gt;      &lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
    &lt;span class="n"&gt;UpdatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Certainly I think it is preferd to wirte it with embed (please refer to Gorm documents)&lt;br&gt;
but errors occur when I excecuted. I wrote all attributes..(I would like to know better way..)&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// todo.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;gorm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;
    &lt;span class="n"&gt;Text&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Done&lt;/span&gt;      &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;UserID&lt;/span&gt;    &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;User&lt;/span&gt;      &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;If you finish to define your model, you have to wirte mapping of model in gqlgen.yml.&lt;br&gt;
Followings is definition in this case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gin_graphql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;
  &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gin_graphql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Define Schema
&lt;/h3&gt;

&lt;p&gt;What I introduced until now is to prepare to develop in schema drriven, I'll to write the code and logic for api from now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Todo&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;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;updatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&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;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;updatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&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;todos&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Todo&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;users&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&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;todo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FetchTodo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;NewTodo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;EditTodo&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;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;NewUser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;FetchTodo&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;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Mutation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;NewTodo&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;Todo&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;updateTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EditTodo&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;Todo&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;deleteTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Int&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;Todo&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;NewUser&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;User&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;scalar&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above is schema.graphql to realize CRUD. You have to use graphql syntax to write this.&lt;br&gt;
Processes to change resouce is wrriten in Mutations and Processes to read it is wrriten in Query.&lt;br&gt;
And Types you need is also defined in schema.graphql.&lt;/p&gt;

&lt;p&gt;Until now, you got reday to generate code and you start to edit resolver.In resolver, IO is defined by schema.graphql and it is generated automatically.&lt;br&gt;
So you focus on writing logic between input and output.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implemntaion Resolver
&lt;/h3&gt;

&lt;p&gt;In resolver, write code to get data from database or create some records.&lt;br&gt;
You have to know that resolver is not overwritten when it is already exist.&lt;/p&gt;

&lt;p&gt;Following is resolver I wrote. I can't explain all because it is about gorm and bored for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Resolver&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Resolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;MutationResolver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mutationResolver&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Resolver&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="n"&gt;QueryResolver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;queryResolver&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&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="n"&gt;mutationResolver&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Resolver&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mutationResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;CreateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;NewUser&lt;/span&gt;&lt;span class="p"&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;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mutationResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;CreateTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&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;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;input&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="n"&gt;UserID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mutationResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;UpdateTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;EditTodo&lt;/span&gt;&lt;span class="p"&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;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&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;input&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;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;First&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mutationResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;DeleteTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&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;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&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;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;First&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;queryResolver&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Resolver&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queryResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;FetchTodo&lt;/span&gt;&lt;span class="p"&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;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Preload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;First&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&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="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queryResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Todos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Preload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todos&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queryResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run
&lt;/h3&gt;

&lt;p&gt;Finally, you can run your code if you finish process I introduced.&lt;br&gt;
The entrypoint of the repositry I prepared is cmd/app/main.go so you can run following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;development&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should pass env in this command because I implemented it to load configuration by env.&lt;br&gt;
When you success to run the server, you can try it on &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Stack Points
&lt;/h2&gt;

&lt;p&gt;Next, I will write about points I stacked while I was building.&lt;/p&gt;
&lt;h3&gt;
  
  
  How can I define type of Time like CreatedAt and Updated?
&lt;/h3&gt;

&lt;p&gt;Schema Types are only 5.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ID&lt;/li&gt;
&lt;li&gt;Int&lt;/li&gt;
&lt;li&gt;Float&lt;/li&gt;
&lt;li&gt;String&lt;/li&gt;
&lt;li&gt;Boolean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we have to define types we need such as Date.&lt;/p&gt;

&lt;p&gt;When I create this sample, I'm stack here but I found gqlgen provide Time Type so I can use it.&lt;/p&gt;

&lt;p&gt;You only do like this as above schema definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;scalar&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you declare the type, the type is mapped to Go Embeded tim.Time Type.&lt;br&gt;
Gqlgen support Map, Upload and Any type so if you want to use their type, only declare it with scalar declaration.&lt;/p&gt;
&lt;h3&gt;
  
  
  Error Occured in Gorm Model while I generate code.
&lt;/h3&gt;

&lt;p&gt;This problem is not resolved. I got away with it by workaround though..&lt;br&gt;
I defined a model with gorm embed type but error occured during generation...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;gorm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I got away with writing all attributes but it is not good.&lt;br&gt;
If anyone know better way, I would like to teach me.&lt;/p&gt;
&lt;h3&gt;
  
  
  Get association model while I get list
&lt;/h3&gt;

&lt;p&gt;This is about not GraphQL but Gorm. I often get list which include associated model so I tried it in this sample, too.&lt;br&gt;
That is simpler than I expeceted. All you need is to add fields to struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Todo&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;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="n"&gt;updatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Time&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 example, when you define Todo model, you can do that by adding userId and user fields to Todo model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Preload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add this line to resolver.&lt;/p&gt;

&lt;p&gt;You already write preload clasue so you already solved N+1 problem.&lt;br&gt;
This is sql when I execute.You can make sure that users query is preloaded.&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="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gin_graphql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;`todos`&lt;/span&gt;  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`todos`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nv"&gt;`todos`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt; &lt;span class="n"&gt;affected&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;returned&lt;/span&gt; &lt;span class="p"&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;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gin_graphql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;`users`&lt;/span&gt;  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nv"&gt;`users`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt; &lt;span class="n"&gt;affected&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;returned&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrrap Up
&lt;/h2&gt;

&lt;p&gt;I tryied to build hot stacks of Web API and Graphql.&lt;/p&gt;

&lt;p&gt;I currently feel the limit of REST API while I develop system with it so I feel stronger the good points of graphql.&lt;br&gt;
In REST API, When I create new endpoint, I have to write code to request that endpoint in client-side.&lt;/p&gt;

&lt;p&gt;In GraphQL, if you define schema once, you can fetch necessary resouce anytime.&lt;br&gt;
When I develop api in REST, I think how I don't depned on frontend but I often need to change code of server-side code when the front is changed.&lt;/p&gt;

&lt;p&gt;I think such problems will be solved by GraphQL (many people say so though..)&lt;br&gt;
Certainly, I learn it deeply and I would know that drawbacks and I can never know that now but I can feel that potential.&lt;/p&gt;

&lt;p&gt;If you are familiar with REST or are sick of creating Web API, try GraphQL&lt;/p&gt;

&lt;p&gt;Thank you,&lt;/p&gt;

</description>
      <category>go</category>
      <category>graphql</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
