Y'know, I tried using Erlang/OTP with rebar3 and cowboy to make a web app. And it turns out that I couldn't even figure out where to put my code, much less how to run it.
It seems a lot of people are having success with Erlang but I can't figure out how these applications actually run; it almost seems like there isn't a single step-by-step tutorial on the Internet for setting up an Erlang system using "best practices."
Am I just missing something? Because I feel like I'm hugely missing out.
It might be worth looking at how Phoenix[0] does it (or, you know, just consider using Elixir/Phoenix). Phoenix runs on cowboy out of the box and makes setting up a web app a snap:
$ mix phoenix.new my_app
which then sets up the directory structure for you to just run
$ mix phoenix.server
and have cowboy serving your webapp. The guides then tell you which files to add new routes, controllers, models, etc (in a way similar to Django or Rails). All that said, it's in Elixir at that point, but maybe you could still infer how the applications and gen servers and whatnot are structured from it.
It may be worth asking josevalim and chrismccord in #elixir-lang for tips on setting it up, since they obviously must know how to set up cowboy pretty well to build a system on top of it.
I think Erlang and things like cowboy and OTP are absolutely amazing for the web, but Elixir has made things 100x easier to get up and running with them.
You can also clone the repo and checkout the examples:
Make sure you have erlang installed
$ cd examples/hello_world
$ make
$ ./_rel/hello_world_example/bin/hello_world_example start
OR
$ ./_rel/hello_world_example/bin/hello_world_example console
This gets a Cowboy application up and running, but it doesn't tell you what to do to write your own Cowboy application, and doesn't give you a very firm understanding of either how the hello_world example works, or how to modify it to suit your needs.
As someone who's been down this road in the past, unless you're already rather familiar with Erlang and OTP's conventions, the gap between the User's Guide and the API documentation is far too large to make connecting information you learn from one with information you learn from the other easy.
I've summarized my personal struggle with the Cowboy user's guide and documentation in my other comment in the thread. Please read that comment before you downvote this one. :)
As far as I know there's no such thing as a `Cowboy application`. They're all Erlang/OTP applications. Sure, there's a learning curve associated with OTP apps, but since Erlang is a bit of an exotic language, I think it's understandable.
If you'd like to learn about the concepts behind an OTP application, you can read this guide: http://learnyousomeerlang.com/building-otp-applications or the Erlang documentation for OTP apps (which is pretty good I think).
Another viable option in my opinion would be to just look into the Phoenix framework for the Elixir language. Under the hood it uses cowboy. And it feels a lot like Rails.
I guess you didn't read my other comment in this thread. Please read it. ;)
> As far as I know there's no such thing as a `Cowboy application`.
From one pedant to another: "I know that." >:)
However, there is (to put it loosely in OTP terms) a set of Cowboy behaviours. Your application is expected to implement one or more of these. While the API for these behaviours is reasonably documented, the Cowboy equivalent of the -say- gen_server "User's Guide" is so sparse as to be almost non-existent.
I think one reasonable strategy of learning how some piece of software works or is meant to be used – especially when documentation is poor – is to just look at the source code (tests included).
I'm just getting started with the Phoenix framework, and I'm learning Elixir at the same time and reading through the source code helps me a lot, because:
1. I can check out how things are implemented
2. I get to read some idiomatic Elixir which helps me learn the language better
One can get reasonable understanding of software at the interplay between reading the docs and reading the source code.
I generally agree that -in the absence of sufficient documentation- reading the tests and source for the project is generally the best way to learn how to use a project.
However. If the language the project is written in is wildly unfamiliar to you, and you've never had experience with a similar language, then this technique is often... less than satisfying.
From your comments, it appears that you have more than a passing familiarity with Erlang/OTP. You have to admit that it would be substantially harder to understand both Elixir and Phoenix without your understanding of Erlang. :)
cowboy's documentation is pretty poor and there's no good 'getting started with cowboy' thing i can point you at, but this is pretty good for erlang in general:
Have you seen [1]? I found it very useful when getting starting with cowboy, though I had prior experience with Erlang.
It walks through a simple "Hello world" application starting with creation from template (erlang.mk), and discusses static files, SSL, websocket.. A very good first guide in my opinion. Though it doesn't really cover other techniques like how to architect your application or interact with a database.
Yes, I had the the same experience.
I started to learn Erlang for growing my personal skills, and because I love functional programming. There are a lot of books about Erlang itself, but when I started to try some http service I found a lack of documentations and step by step tutorial
My first attempt at making a simple Cowboy application was less than successful. I found the documentation spotty, inconsistent, and very difficult to understand. After about 45 minutes of really frustrated dicking around, I figured out how to make a simple HTTP server that allowed me to handle simple HTTP requests. I had to write code to switch on the passed-in HTTP verb, but everything worked, more or less. I could serve HTTP requests, but my code crashed after every request. (This was -of course- not fatal, but a bit of a performance killer.) Pipelined requests didn't work due to server connection resets. (Again, not fatal, just perf-diminishing.) I was utterly unable to get cowboy_rest to work.
Several months later, with a lot of additional Erlang experience under my belt, I come back to the documentation, and it's -somehow- 60->70% comprehensible. I figured out what was wrong with my simple HTTP server. (I was calling my request handler in init, rather than returning {ok, Req, []}, and letting Cowboy call my request handler later.) I still can't get cowboy_rest to work, but (OTOH) I haven't spent more than five minutes trying to get it to work since my first attempt way back when.
I don't know how much experience you have with Erlang, so I'll give you some basic advice that might be entirely unhelpful. Feel free to ask additional questions. Also feel free to ask questions on the erlang-questions mailing list. [0] Everyone who regularly posts there is very helpful. Many (most?) of them use Erlang professionally.
Anyway. Advice:
Projects/frameworks like OTP and Cowboy provide a callback API that application code is expected to conform to. Cowboy's documentation for this API is kind of all over the place, [1] but OTP's is well organized. [2]
Because Erlang tries to eschew global state as much as it can, OTP has a convention that one of the values in the tuple returned from an callback is the state for that particular instance of your application code. This State variable seems to always be the last element in the returned tuple, and the last argument to your callback function. State can be any Erlang term; it only has meaning to your application code. If your callbacks don't care about state, then you can pass anything as state. Many other frameworks have adopted this convention; it's a pretty good one.
Cowboy appears to be a pretty good HTTP/SPDY server. The beginner's documentation needs a LOT of love. (Even now, I had difficulty trying to piece together that walk through the docs in the footnote.) Given that it's a one-man shop, it's surprising that the docs are in as good a shape as they are; documentation isn't easy. :) But, still...
Anyway, questions? Comments? Ask away either here, or on the erlang-questions mailing list. :)
[2] For example, the docs for OTP's application API: http://www.erlang.org/doc/man/application.html or the gen_server API: http://www.erlang.org/doc/man/gen_server.html The parts before the "CALLBACK FUNCTIONS" section are functions you use to manipulate an application or gen_server. The bits after are functions you implement in your module that the application or gen_server machinery will call.
Just curious, was erlang.mk around and did you use the bootstrapped release / cowboy_http template [1] when creating your first application? Based on some things you mention, it makes it sound like you were writing from scratch while referencing the docs. :-)
I also got started from the cowboy user guide (with prior Erlang experience), but found it relatively easier, as I used the template, then cross-referenced the idiomatic template with the docs as I worked through them (tweaking 'knobs' as I went along), which worked well in helping me understand the design.
Along with the Erlang mailing list you've mentioned, I would also like to mention #ninenines (and #erlang for more general questions) on freenode. Very helpful communities!
* It enforces warnings-as-errors. This is a personal preference, but I hate this while developing. I want to iterate, not have to clean up unused variables that I already know about.
* It -until very recently- failed so, so, so hard when run with parallel make. I -at first- idly wondered if -somehow- Cowboy application builds were just non-deterministic. I then remembered that I aliased 'make' to 'make -j3'. Building with 'make -j1' fixed the build and put me squarely in the Rebar camp.
Rebar is just a far better fit for how I work.
> ...did you use the cowboy_http / bootstrapped release template...
Nah.
When learning new things, if I'm not in a rush, I tend -at first- to avoid templates. I've been burned by boilerplate code in the past, and have had boilerplate code cover up the true crawling horror that was more than a couple of APIs.
I'd rather initially do things "from scratch" [0] so that I can better evaluate the thing I'm learning, and the quality of its supporting documentation, or -if the documentation is inadequate- the explanatory power of its test suite and other sample code.
I did -however- read Cowboy's Getting Started guide, along with a huge chunk of the documentation. I actually started with the API documentation, figuring that it was going to be like erlang.org's documentation. Whoops! [1]
[0] And by that, I don't mean "from first principles". I'm quite happy to read an example, partially or fully digest it, then paste it into my text editor.
[1] Again, I know how good erlang.org's documentation is and how very much work it is to make such high-quality documentation. I don't mean to slight Loïc Hoguin. :)
It seems a lot of people are having success with Erlang but I can't figure out how these applications actually run; it almost seems like there isn't a single step-by-step tutorial on the Internet for setting up an Erlang system using "best practices."
Am I just missing something? Because I feel like I'm hugely missing out.