<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Logan Bresnahan on Medium]]></title>
        <description><![CDATA[Stories by Logan Bresnahan on Medium]]></description>
        <link>https://medium.com/@loganbbres?source=rss-23b4862e66e1------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*omTwA0K1xDUDGtg55cfOdg.jpeg</url>
            <title>Stories by Logan Bresnahan on Medium</title>
            <link>https://medium.com/@loganbbres?source=rss-23b4862e66e1------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 01:12:14 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@loganbbres/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Meow. A process manager for development.]]></title>
            <link>https://medium.com/@loganbbres/meow-a-process-manager-for-development-3b636d121f5e?source=rss-23b4862e66e1------2</link>
            <guid isPermaLink="false">https://medium.com/p/3b636d121f5e</guid>
            <category><![CDATA[shell]]></category>
            <category><![CDATA[developer-tools]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[productivity]]></category>
            <dc:creator><![CDATA[Logan Bresnahan]]></dc:creator>
            <pubDate>Sun, 23 May 2021 18:28:31 GMT</pubDate>
            <atom:updated>2021-05-27T15:03:00.041Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*IMWacghg5ORzeCNW29Gx1Q.png" /></figure><p>Meow is a pure shell program that manages booting and killing any given amount of processes for your development workflow. It gives you the ability to boot/kill these processes in different terminal tabs automatically. Scroll to the bottom to see a quick visual representation on how Meow reads and organizes your processes. To see everything Meow has to offer checkout its repo. <a href="https://github.com/LoganBresnahan/meow">https://github.com/LoganBresnahan/meow</a></p><p>As a web developer, I feel elated at the current state of web development. It continues to grow more vibrant and exciting everyday! There are so many wonderful tools to make a web dev’s life easier and more productive. Personally, I do a ton of work with Rails, Webpack, and Elixir! The creators behind these tools and frameworks have made spinning up a new website easier than ever….but can it get even easier?</p><p>My normal development setup consists of a booting up a backend, frontend, and cache server. So now we have 3 processes to boot-up somehow. Not a problem! There are some really cool tools out there such as Overmind and the Foreman family of tools that manage Procfile based applications. Essentially reading commands off of the Procfile and running them. Each tool respectively has it’s own features that really shine, but I found they didn’t do exactly what I wanted.</p><p>As a Rails developer I use the pry gem a lot for debugging. pry is a repl (read evaluate print loop) which allows you to input text into the terminal within the context of your application similar to using debugger in JavaScript. When using Foreman to boot up my servers for development I noticed that pry doesn&#39;t work as expected. It &quot;works&quot; but you simply can&#39;t see what you&#39;re typing. Foreman wasn&#39;t made to receive input. Overmind on the other hand is closer to what I want but still misses the mark. Like foreman, it doesn&#39;t handle receiving input when using a repl. However, Overmind is built with tmux. You can simply open a new tab and connect it to your desired process that was started with Overmind and huzzah! My pry session is working and I can see what I&#39;m typing. HOWEVER, I&#39;m too lazy for this approach. I don&#39;t want to open up a new tab and handle closing it. I just want everything to be setup with one simple command.</p><p>Enter Meow. I created Meow as simple development tool that would let me add commands to a single file, similar to a Procfile, but also give me the ability to boot these commands into a different terminal tab without having to do it manually. All the while, making sure that debugging tools, such as pry, would just work. Not only that, I wanted the option to fine tune how and when processes would die. With Meow you can tell a newly spawned terminal tab to &quot;expire&quot; or &quot;endure&quot; when the main process is terminated. Check out the Readme from the link above to learn all the options available with Meow. Below is an example config file Meow reads from to manage your commands.</p><pre><em># Hi I&#39;m a comment. I must start at the beginning of a line.</em><br><br><strong>--start-config</strong><br><br><em># For an explanation of these config options check out the Readme.</em><br><strong>writable-relative-directory=tmp<br>auto-check-updates=true<br>apple-tab-spawn-delay=0.75<br>unix-shell=bash<br>kill-signal=15<br><br>--end-config</strong><br><br><em># To execute these commands just type &quot;meow&quot; in your terminal<br># If you want to execute just one or a selection of these groups <br># you can give Meow command line arguments &quot;meow 0 2&quot;. <br># This will only boot the commands listed in the first and<br># last groups.</em><br><strong>--start-commands</strong><br><br><em># I&#39;m the first command of a group so I exist in the foreground<br></em><strong>bundle exec rails server</strong><em><br># Commands after the first exist in the background.</em><br><strong>yarn start:dev</strong><br><br><strong>--new-tab-expire</strong><br><em># New tab expire means it closes when you terminate the first group.</em><br><em><br># We can change directories!</em><br><strong>-cd $HOME/my_project_two</strong><br><br><em># I&#39;m the foreground command of this new terminal tab.</em><br><strong>iex -S mix</strong><br><em># I&#39;m off to the background.</em><br><strong>npx webpack --mode=development --watch=true</strong><br><br><strong>--new-tab-endure</strong><br><em># New tab endure means these commands do not exit when you<br># kill the first group.</em><br><br><strong>redis-server</strong><br><br><strong>--end-commands</strong></pre><p><em>Originally published at </em><a href="https://dev.to/loganbresnahan/meow-a-process-manager-for-development-3i5g"><em>https://dev.to</em></a><em> on May 23, 2021.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3b636d121f5e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Currying With Elixir and Basic Operators]]></title>
            <link>https://medium.com/@loganbbres/currying-with-elixir-and-basic-operators-33bb68dcca4c?source=rss-23b4862e66e1------2</link>
            <guid isPermaLink="false">https://medium.com/p/33bb68dcca4c</guid>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[currying]]></category>
            <category><![CDATA[elixir]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Logan Bresnahan]]></dc:creator>
            <pubDate>Sun, 23 Dec 2018 03:41:49 GMT</pubDate>
            <atom:updated>2018-12-23T03:41:49.830Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*A9OP1IxpfYsoQh--LFrs7Q.jpeg" /><figcaption>image by <a href="https://pixabay.com/en/color-spices-saffron-powder-bags-1028428/">3dman_eu</a></figcaption></figure><p>I recently learned that the object oriented language, Ruby has built in currying. This is pretty cool considering Ruby emphasized object oriented programming rather than functional programming. Here is an example of some Ruby code utilizing currying with an add lambda.</p><pre>add = lambda { |a, b| a + b }</pre><pre>curried_add = add.curry.(1)<br>curried_add.(2) #outputs 3</pre><p>Normally the add lambda would force us to pass two arguments when calling add, but by chaining in the curry method we bypass this and save the curried lambda in out curried_add variable which we can then call with the second argument later. There is a shorthand for calling our curried lambda in Ruby 2.5 with yield_self which relates to how we can write this in Elixir.</p><pre>add = lambda { |a, b| a + b }</pre><pre>add.curry.(1).yield_self { |curried| curried.(2) } #outputs 3</pre><p>How would these two examples look in Elixir?</p><pre>add = fn<br>  ({a, b}) -&gt;<br>    a + b<br>  ({a}) -&gt;<br>    fn(b) -&gt; a + b end<br>  end</pre><pre>add.({1, 2}) #outputs 3</pre><pre>curried_add = add.({1})<br>curried_add.(2) #outputs 3</pre><p>Elixir doesn’t have built in currying, so you have to implement something yourself. We are using anonymous functions because they resemble lambdas in Ruby. We use function overloading in our anonymous function to determine which function match to run. You may be wondering why we wrap our arguments in a tuple for our add function. That’s because anonymous functions utilizing function overloading can’t have a different arity. We get around this by using the tuples. Notice, that when passing in only one integer in our tuple argument, our add function returns another function. Our curried_add variable gets assigned to that returned anonymous function which means we can then execute it later. Now for the shorthand.</p><pre>add = fn<br>  ({a, b}) -&gt;<br>    a + b<br>  ({a}) -&gt;<br>    fn(b) -&gt; a + b end<br>  end</pre><pre>add.({1}) |&gt; fn(curried) -&gt; curried.(2) end.() #outputs 3</pre><p>After trying this out I got a little over zealous and implemented a trivial Elixir module that could pass curried functions to other math operations.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0d076189a6cfe938bbcc3cc2bef06f12/href">https://medium.com/media/0d076189a6cfe938bbcc3cc2bef06f12/href</a></iframe><p>This module utilizes a lot of recursion to get the desired result. The basic idea is to pass your starting accumulator (0), the operand, the integers you want to calculate, and whether you want to curry the operation by having the return value be an anonymous function. Albeit, this is trivial as you could also just have the calculation return the actual calculated number and pass that on to the next CurryMath function which would get the same result. ¯\_(ツ)_/¯</p><p>Elixir is awesome, go try some other currying implementations.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=33bb68dcca4c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Elixir WebSocket Chat Example w/o Phoenix]]></title>
            <link>https://medium.com/@loganbbres/elixir-websocket-chat-example-c72986ab5778?source=rss-23b4862e66e1------2</link>
            <guid isPermaLink="false">https://medium.com/p/c72986ab5778</guid>
            <category><![CDATA[elixir]]></category>
            <category><![CDATA[erlang]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[websocket]]></category>
            <category><![CDATA[phoenix-framework]]></category>
            <dc:creator><![CDATA[Logan Bresnahan]]></dc:creator>
            <pubDate>Sun, 02 Dec 2018 19:07:07 GMT</pubDate>
            <atom:updated>2018-12-16T15:17:32.837Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7SYBgrbNOfbD45I3NRxeKA.jpeg" /><figcaption><a href="https://pixabay.com/en/users/sumanley-2265479/">image by sumanley</a></figcaption></figure><p>Using the Cowboy HTTP web server it’s very easy to handle web socket connections in your Elixir application. Keep in mind, this example is not using the Phoenix framework. With Elixir’s tools, you can quickly create a simple web framework.</p><p>Let us start by making a new Elixir application.</p><p>Run mix new my_websocket_app</p><p>Open the <strong>mix.exs</strong> file and make it look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/36295e33257fd5207b9a2fbf16f93a3b/href">https://medium.com/media/36295e33257fd5207b9a2fbf16f93a3b/href</a></iframe><p>Notice the necessary dependencies we need. :cowboy the HTTP server, :plug and :plug_cowboy the HTTP server connection adapters, and :jason the JSON parser. Run mix deps.get to fetch dependencies. Also, notice line 17:</p><p>mod: {MyWebsocketApp, []}</p><p>This is added because we are going to declare MyWebsocketApp as an application that will be monitored by the Erlang VM.<br><a href="https://hexdocs.pm/elixir/Application.html#module-the-application-callback-module">https://hexdocs.pm/elixir/Application.html#module-the-application-callback-module</a></p><p>Open your <strong>my_websocket_app.ex</strong> file and make it look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6baf7b58d59dcb1e60e77aba02c8239f/href">https://medium.com/media/6baf7b58d59dcb1e60e77aba02c8239f/href</a></iframe><p>It is here we are using Elixir’s Application module to tell the Erlang VM that our app is an application to monitor.</p><p>Next, we have the child workers listed that will be supervised by our MyWebsocketApp.Application. First, the Plug.Cowboy configuration. :scheme is set to :http for local development. :plug is set to our MyWebsocketApp.Router plug that we will create. Inside of :options we have :dispatch which is set to our private dispatch/0 function below, and :port is set to 4000.</p><p>More on the dispatch/0 function. What we are doing here is pattern matching on incoming requests to the HTTP server. If a request ends in &quot;/ws/[...]&quot; , that means it will be routed to our MyWebsocketApp.SocketHandler module which is where we will handle web socket connections. What is &quot;[...]&quot;? It matches everything else after &quot;/ws/&quot;. You will see in our JavaScript below, our web socket request path will be &quot;/ws/chat&quot;. &quot;chat&quot; is scooped up by &quot;[...]&quot;. More can be found in the source code for the cowboy router: <a href="https://github.com/ninenines/cowboy/blob/master/src/cowboy_router.erl#L196">https://github.com/ninenines/cowboy/blob/master/src/cowboy_router.erl#L196</a>. Finally regarding dispatch/0, if the request is not matched by &quot;/ws/[...]&quot; then the request gets sent to our router, MyWebsocketApp.Router.</p><p>Lastly, our final child worker is Registry.MyWebsocketApp. We are going to use Elixir’s Registry module as a dispatcher for the incoming web socket messages. <a href="https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-dispatcher">https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-dispatcher</a></p><p>Make a <strong>router.ex</strong> file inside your <strong>lib</strong> directory and make it look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/04025382d11a0cb119ac01ca4b7bb029/href">https://medium.com/media/04025382d11a0cb119ac01ca4b7bb029/href</a></iframe><p>We are using Plug.Router and creating a Plug pipeline that matches on incoming requests and routes them appropriately. get &quot;/&quot; matches to our home route where we use EEx to evaluate our <strong>application.html.eex</strong> file which we will create shortly so we can present the user with with something to see for our upcoming web socket chat example. match _ proceeds to match anything other than &quot;/&quot; . At the top of the file we are using our Jason dependency as our JSON parser and we are using Plug.Static to serve static assets like our <strong>application.js</strong> file we will make. <a href="https://hexdocs.pm/plug/readme.html#plug-router">https://hexdocs.pm/plug/readme.html#plug-router</a></p><p>Make the <strong>application.html.eex</strong> file in your lib directory:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f0388ba75252a4f349540c3497b47dd3/href">https://medium.com/media/f0388ba75252a4f349540c3497b47dd3/href</a></iframe><p>This is super basic HTML that we have created. Just note, we are loading our JavaScript file <strong>application.js</strong>.</p><p>Make a sister directory to <strong>lib </strong>called <strong>priv</strong>, inside that make a <strong>static</strong> directory, finally make a <strong>js</strong> directory inside <strong>static</strong>. Inside the <strong>js </strong>directory, make the <strong>application.js </strong>file:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/00fda88ebbe1029f0d13b1e22928ec97/href">https://medium.com/media/00fda88ebbe1029f0d13b1e22928ec97/href</a></iframe><p>I’m not going to explain this JavaScript in great detail because this post is really about Elixir. We are just throwing this together to make the chat example work. We are opening up a web socket connection and setting event listeners for incoming web socket messages. We also have an event listener in the case the web socket connection is closed, if so, we re-open it. You should also notice when a user hits the submit button we send our data along to the web socket server. Finally note, we are setting the web socket request path to &quot;/ws/chat&quot; because we are going to use that path as a registry key in our Registry, Registry.MyWebsocketApp.</p><p>Now that we have the JavaScript, time to create MyWebsocketApp.SocketHandler. In the <strong>lib</strong> directory make the <strong>socket_handler.ex</strong> file:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1086f0753bef4d9a130e7bd2bbbb794f/href">https://medium.com/media/1086f0753bef4d9a130e7bd2bbbb794f/href</a></iframe><p>At last, the reason you probably clicked on this post. This is our MyWebsocketApp.SocketHandler module that handles web socket connections. First note, we are referencing the :cowboy_websocket module with @behaviour. This makes sure we implement the necessary callbacks that are defined by :cowboy_websocket. Those are init/2, websocket_init/1, websocket_handle/2, and websocket_info/2.</p><p>Inside of init/2 we are going to grab the path from the request and save that to the state variable that gets passed along to the websocket_init/1 function. It is inside this function that we will utilize Elixir’s Registry module. Remember we setup the supervised Registry process in the <strong>my_websocket_app.ex </strong>file? If not, go take another look. We set the :keys options to :duplicate. This means that multiple processes can be registered under one key in the registry. In our case that one key is the web socket request’s path name. Anytime someone opens their browser and travels to the page of our website which makes a web socket request with that path name (&quot;/ws/chat&quot;) a process id number for their web socket connection will be saved in Registry.MyWebsocketApp. The function register/2 that we call on the Registry module actually saves the current process’s pid (process id) implicitly as you will not see it being passed in as an argument. If you want to see what the process’s pid is when your code runs you can add IO.inspect(self()) to the top of the websocket_init/1 function and it will print to your terminal.</p><p>When the browser client actually sends a message utilizing the web socket connection the websocket_handle/2 callback is triggered. This callback has a return value of {:reply, {:text, message}, state}. This actually sends a message back to the client that sent the original web socket message. In our case we want to broadcast that message to every process in the Registry.MyWebsocketApp that shares the same key (users who have made a request to &quot;/ws/chat&quot; by navigating to our home page). This means we use the dispatch/2 function to iterate over all of the pids that are registered and send them the desired message with Process.send/3.</p><p>This is where the special websocket_info/2 callback is utilized. Whenever an<em> Elixir process</em> sends a message to our MyWebsocketApp.SocketHandler the callback is triggered. This callback has a return value just like websocket_handle/2 which returns a message to the original client.</p><p>That’s it! Now we can actually make sure this all works. Start your development server with iex -S mix. Once everything compiles, visit <a href="http://localhost:4000/">http://localhost:4000/</a> in two different browsers just for good measure. As soon as you enter some text in one browser and hit submit you should see it immediately popup in the other browser.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/913/1*mAXl_9x-R1y5tsROTIuiFw.png" /></figure><p>Elixir is amazing! Thanks to all of the hard work by the authors and contributors of the these libraries we are able to make a super easy to use chat server in a very short time. Thanks so much for reading!</p><p>References throughout this post:<br>1. <a href="https://hexdocs.pm/elixir/Application.html#module-the-application-callback-module">https://hexdocs.pm/elixir/Application.html#module-the-application-callback-module</a><br>2. <a href="https://github.com/ninenines/cowboy/blob/master/src/cowboy_router.erl#L196">https://github.com/ninenines/cowboy/blob/master/src/cowboy_router.erl#L196</a><br>3. <a href="https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-dispatcher">https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-dispatcher</a><br>4. <a href="https://hexdocs.pm/plug/readme.html#plug-router">https://hexdocs.pm/plug/readme.html#plug-router</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c72986ab5778" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Turning an Elixir Mix Application into an API Micro-Service w/o Phoenix]]></title>
            <link>https://medium.com/@loganbbres/turning-an-elixir-mix-application-into-an-http-micro-service-w-o-phoenix-fff2906b576b?source=rss-23b4862e66e1------2</link>
            <guid isPermaLink="false">https://medium.com/p/fff2906b576b</guid>
            <category><![CDATA[phoenix-framework]]></category>
            <category><![CDATA[elixir]]></category>
            <category><![CDATA[mix]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[microservices]]></category>
            <dc:creator><![CDATA[Logan Bresnahan]]></dc:creator>
            <pubDate>Thu, 05 Jul 2018 01:21:33 GMT</pubDate>
            <atom:updated>2018-07-23T01:50:10.600Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*y3BX0YDdTBZQJsmu0mjEfg.jpeg" /></figure><p>Have you ever wanted to create a tiny little service that is just an endpoint for requests from other applications? If so, Elixir(<a href="https://elixir-lang.org/">1</a>) and its build tool Mix(<a href="https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html">2</a>) make it dead easy.</p><p>Assuming you’ve installed Elixir on your system, let’s fire up a new Mix application. Please Note, this tutorial was done using Elixir 1.6.5.</p><pre>mix new my_micro_service</pre><p>Go ahead and explore the file structure of your new mix application. As you can see it’s pretty minimal. Open up the <em>mix.exs</em> file that exists in the top level of the project’s directory. This file helps us configure our application, and most of your time here will be for installing the dependencies you want to add to the application. Take a look at the public <strong>application/0</strong> and private <strong>deps/0</strong> functions defined at the bottom of the file.</p><pre>def application do<br>  [<br>    extra_applications: [:logger]<br>  ]<br>end</pre><pre>defp deps do<br>  [<br>    <em># {:dep_from_hexpm, &quot;~&gt; 0.3.0&quot;},<br>    # {:dep_from_git, git: &quot;https://github.com/elixir-lang/my_dep.git&quot;, tag: &quot;0.1.0&quot;},<br>  </em>]<br>end</pre><p>The comments in the <strong>deps/0</strong> function are just explaining how to install dependencies. Delete those comments and make your functions look like these:</p><pre>def application do<br>  [<br>    extra_applications: [:logger, :cowboy, :plug, :poison],<br>    mod: {MyMicroService, []}<br>  ]<br>end</pre><pre>defp deps do<br>  [<br>    {:cowboy, &quot;~&gt; 2.4&quot;},<br>    {:plug, &quot;~&gt; 1.6&quot;},<br>    {:poison, &quot;~&gt; 3.1&quot;}<br>  ]<br>end</pre><p>We are going to install Cowboy(<a href="https://ninenines.eu/">3</a>, <a href="https://github.com/ninenines/cowboy">4</a>) our the HTTP server, Plug(<a href="https://github.com/elixir-plug/plug">5</a>) an interface for handling the server, and Poison(<a href="https://github.com/devinus/poison">6</a>) our JSON parser. To install the dependencies, run the command:</p><pre>mix deps.get</pre><p>Now, find the <em>my_micro_service.ex</em> file within the <em>lib </em>folder. Delete the code inside the definition of the module and make it look like this:</p><pre>defmodule MyMicroService do<br>  use Application</pre><pre>  def start(_type, _args) do<br>    children = [<br>      Plug.Adapters.Cowboy2.child_spec(<br>        scheme: :http,<br>        plug: MyMicroService.Router,<br>        options: [port: 4000]<br>      )<br>    ]</pre><pre>    opts = [strategy: :one_for_one, name: MyMicroService.Supervisor]<br>    Supervisor.start_link(children, opts)<br>  end<br>end</pre><p>There is a lot going on here and I urge you to read the documentation of supervision trees(<a href="https://hexdocs.pm/elixir/Supervisor.html">7</a>) in Elixir. What we’re essentially doing is starting up a supervised process that starts the HTTP server for us on port 4000.</p><p>Now, make a <em>router.ex </em>file in your <em>lib</em> directory and make it look like this:</p><pre>defmodule MyMicroService.Router do<br>  use Plug.Router</pre><pre>  plug :match<br>  plug Plug.Parsers,<br>    parsers: [:json],<br>    pass: [&quot;application/json&quot;],<br>    json_decoder: Poison<br>  plug :dispatch</pre><pre>  get &quot;/hello&quot; do<br>    send_resp(conn, 200, &quot;Hello World!&quot;)<br>  end</pre><pre>  match _ do<br>    send_resp(conn, 404, &quot;Page Missing&quot;)<br>  end<br>end</pre><p>We are creating a Plug pipeline with this module. Router(<a href="https://hexdocs.pm/plug/Plug.Router.html#content">8</a>), match, parsers, and dispatch are all plugs available from the Plug dependency. Down below we define some routes for our application to respond to. The <strong>match </strong>route might be a little confusing, but all it’s doing is catching any path that we didn’t define and then sending the user a 404.</p><p>At this point we can test these routes! Run your application with the following :</p><pre>iex -S mix run</pre><p>It might take a few seconds for your project to compile when it’s finished go to, <a href="http://localhost:4000/hello">http://localhost:4000/hello</a></p><p>You should see: “Hello World!”</p><p>Now go to a route we didn’t set. <a href="http://localhost:4000/nope">http://localhost:4000/nope</a></p><p>You should see: “Page Missing”</p><p>The last thing we’ll do is create and new endpoint file so we can handle our logic for our “hello” route outside of the <em>router.ex</em> file. Make a new <em>api </em>directory in the <em>lib</em> folder and new file in the <em>api </em>directory titled, <em>hello_endpoint.ex</em>. Make the new file look like this:</p><pre>defmodule MyMicroService.API.HelloEndpoint do<br>  import Plug.Conn</pre><pre>  def show(conn) do<br>    send_resp(conn, 200, &quot;Hello World!&quot;)<br>  end<br>end</pre><p>Let’s adjust the <em>router.ex </em>file to handle our changes. Alias the API module namespace and change the get route.</p><pre>defmodule MyMicroService.Router do<br>  use Plug.Router<br>  alias MyMicroService.API</pre><pre>  plug :match<br>  plug Plug.Parsers,<br>    parsers: [:json],<br>    pass: [&quot;application/json&quot;],<br>    json_decoder: Poison<br>  plug :dispatch</pre><pre>  get &quot;/hello&quot; do<br>    API.HelloEndpoint.show(conn)<br>  end</pre><pre>  match _ do<br>    send_resp(conn, 404, &quot;Page Missing&quot;)<br>  end<br>end</pre><p>Close your previous server with Ctrl-c Ctrl-c. Fire up a new server and see if everything is still working.</p><p>That was a very basic example of how to turn an Elixir Mix application into a fun little API micro-service. There is much more that you can do with the tools I’ve presented here. Check out the documentation and see what else you can build.</p><ol><li><a href="https://elixir-lang.org/">https://elixir-lang.org/</a></li><li><a href="https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html">https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html</a></li><li><a href="https://ninenines.eu/">https://ninenines.eu/</a></li><li><a href="https://github.com/ninenines/cowboy">https://github.com/ninenines/cowboy</a></li><li><a href="https://github.com/elixir-plug/plug">https://github.com/elixir-plug/plug</a></li><li><a href="https://github.com/devinus/poison">https://github.com/devinus/poison</a></li><li><a href="https://hexdocs.pm/elixir/Supervisor.html">https://hexdocs.pm/elixir/Supervisor.html</a></li><li><a href="https://hexdocs.pm/plug/Plug.Router.html#content">https://hexdocs.pm/plug/Plug.Router.html#content</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fff2906b576b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Adding Stimulus JS to an Elixir/Phoenix Project]]></title>
            <link>https://medium.com/@loganbbres/adding-stimulus-js-to-an-elixir-phoenix-project-f492a4630f22?source=rss-23b4862e66e1------2</link>
            <guid isPermaLink="false">https://medium.com/p/f492a4630f22</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[stimulus]]></category>
            <category><![CDATA[phoenix]]></category>
            <category><![CDATA[phoenix-framework]]></category>
            <category><![CDATA[brunch]]></category>
            <dc:creator><![CDATA[Logan Bresnahan]]></dc:creator>
            <pubDate>Mon, 19 Mar 2018 02:12:24 GMT</pubDate>
            <atom:updated>2018-07-04T20:06:14.128Z</atom:updated>
            <content:encoded><![CDATA[<figure><a href="https://pixabay.com/en/dragon-the-myth-story-god-god-ll-872934/"><img alt="" src="https://cdn-images-1.medium.com/max/960/1*8jQiVSymT8zL5qTawGO3cg.jpeg" /></a><figcaption>Image By <a href="https://pixabay.com/en/users/jsbaw7160-828420/">jsbaw7160</a></figcaption></figure><p>Stimulus(<a href="https://stimulusjs.org/">1</a>) is a new JavaScript framework from the team behind Ruby on Rails(<a href="https://m.signalvnoise.com/stimulus-1-0-a-modest-javascript-framework-for-the-html-you-already-have-f04307009130">2</a>).</p><p>Though Stimulus will most likely be used in various Rails projects, that doesn’t mean we can’t use it in other frameworks such as Phoenix.</p><p>If you haven’t already created a new Phoenix project, go ahead and run:</p><pre>mix phx.new phoenix_with_stimulus</pre><p>Continue to follow the prompt; installing your dependencies, changing into the new project directory, creating your development database, and testing the local server. Notice we are using Brunch(<a href="https://brunch.io/">3</a>) as our build tool. Most people using Stimulus will probably be using Webpack(<a href="https://webpack.js.org/">4</a>), but Phoenix comes with Brunch by default. Let’s use what we have and continue with Brunch.</p><p>Now to install Stimulus. Change into your <em>assets</em> directory:</p><pre>cd assets</pre><p>Then install the necessary dependencies:</p><pre>npm install --save stimulus<br>npm install --save-dev babel-plugin-transform-class-properties<br>npm install --save-dev babel-preset-env</pre><p>We also need to edit the <em>brunch-config.js</em> file in the <em>assets</em> directory. Specifically, we are going to edit the plugins section. Make sure yours looks like this:</p><pre>plugins: {<br>  babel: {<br>    <em>// Do not use ES6 compiler in vendor code<br>    </em>ignore: [/vendor/],<br>    presets: [<em>&quot;env&quot;</em>],<br>    plugins: [<em>&quot;transform-class-properties&quot;</em>]<br>  }<br>},</pre><p>To test our setup I’m going to be pulling these examples almost directly from the Stimulus Handbook(<a href="https://stimulusjs.org/handbook/introduction">5</a>) with a few minor name changes to make things as quick as possible.</p><p>From inside the <em>assets</em> directory; change into the <em>js</em> directory, create a <em>controllers</em> directory, change into it, and create a <em>pageController.js</em> file:</p><pre>cd js<br>mkdir controllers<br>cd controllers<br>touch pageController.js</pre><p>Now, we are going to find our <em>app.js</em> file and make some changes. The file should be in your <em>js</em> directory. Add this JavaScript to the end of the file:</p><pre>import { Application } from <em>&quot;stimulus&quot;</em></pre><pre>import PageController from <em>&quot;./controllers/pageController&quot;</em></pre><pre>const application = Application.start()<br>application.register(<em>&quot;page&quot;</em>, PageController)</pre><p>Let’s edit the newly created <em>pageController.js</em> file by adding:</p><pre>import { Controller } from <em>&quot;stimulus&quot;</em></pre><pre>export default class extends Controller {<br>  static targets = [ <em>&quot;myInput&quot;</em> ]</pre><pre>  alertText() {<br>    const element = this.myInputTarget<br>    const myInput = element.value<br>    alert(<em>`My ${myInput}`</em>)<br>  }<br>}</pre><p>Continue on to find and edit the <em>index.html.eex</em> file that should already exist within the directory structure <em>lib/phoenix_with_stimulus_web/templates/page</em>. Delete everything in that file and add:</p><pre>&lt;div data-controller=<em>&quot;page&quot;</em>&gt;<br>  &lt;input data-target=<em>&quot;page.myInput&quot;</em> type=<em>&quot;text&quot;</em>&gt;<br>  &lt;button data-action=<em>&quot;click-&gt;page#alertText&quot;</em>&gt;Click Here&lt;/button&gt;<br>&lt;/div&gt;</pre><p>That’s just about it. Lets make sure we are in the top level of our project directory and then spin up our development server with:</p><pre>mix phx.server</pre><p>In your browser navigate to <a href="http://localhost:4000/">http://localhost:4000/</a><br>You should be seeing a screen like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cjpkVtUqDlQWd1bQNA8X8Q.png" /></figure><p>Type in some input and hit “Click Here”. You should see an alert from your browser with your input!</p><p>I hope this was helpful in getting you started using Stimulus JS with Phoenix! For explanations to these code samples and more detail on Stimulus please see the official handbook(<a href="https://stimulusjs.org/handbook/introduction">5</a>).</p><p>1. <a href="https://stimulusjs.org/">https://stimulusjs.org/</a><br>2. <a href="https://m.signalvnoise.com/stimulus-1-0-a-modest-javascript-framework-for-the-html-you-already-have-f04307009130">https://m.signalvnoise.com/stimulus-1-0-a-modest-javascript-framework-for-the-html-you-already-have-f04307009130</a><br>3. <a href="https://brunch.io/">https://brunch.io/</a><br>4. <a href="https://webpack.js.org/">https://webpack.js.org/</a><br>5. <a href="https://stimulusjs.org/handbook/introduction">https://stimulusjs.org/handbook/introduction</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f492a4630f22" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>