馃 A practical web framework for Gleam
1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Wisp - A practical web framework for Gleam</title>
8 <link rel="stylesheet" href="style.css">
9</head>
10
11<body>
12 <section class="home-hero">
13 <nav>
14 <a href="https://github.com/lpil/wisp">Source & Guides</a>
15 <a href="https://hexdocs.pm/wisp">API Docs</a>
16 <a href="https://github.com/sponsors/lpil">Sponsor</a>
17 </nav>
18 <img src="./images/wordmark.svg" alt="Wisp">
19 <p>
20 A practical web framework for Gleam
21 </p>
22 </section>
23
24 <ul class="content-width features">
25 <li>
26
27 <h2>
28 Perfectly productive
29 </h2>
30 <p>
31 Wisp is simple, type safe, and entirely free from confusing magic. Make
32 development as stress-free as possible whether you're starting a new
33 prototype or maintaining a large system.
34 </p>
35 </li>
36
37 <li>
38 <h2>
39 Flipping fast
40 </h2>
41 <p>
42 Thanks to the Mist HTTP server and the mighty multithreaded BEAM
43 runtime Wisp applications are fast, even at the 99th percentile during a
44 big burst of traffic. In benchmarks Wisp can outperform Go, NodeJS, and
45 Elixir Phoenix + Cowboy.
46 </p>
47 </li>
48
49 <li>
50 <h2>
51 Totally testable
52 </h2>
53 <p>
54 If your application matters then you're going to want to test it. A Wisp
55 web application is as easy to test as any regular Gleam function, and an
56 assortment of useful test helpers are provided to keep your tests
57 concise.
58 </p>
59 </li>
60
61 <li>
62 <h2>
63 Really reliable
64 </h2>
65 <p>
66 Scrambling to fix problems in production is stressful, so Wisp uses
67 Gleam's type safety and the BEAM's fault tolerance help prevent those
68 panicked late night phone calls from your boss.
69 </p>
70 </li>
71 </ul>
72
73 <section class="content-width">
74 <h2>OK, but what does Wisp actually give you?</h2>
75 <ul>
76 <li>Composable middleware, with lots of useful ones built-in.</li>
77 <li>Type safe routing with good old fashioned pattern matching.</li>
78 <li>Parsing of JSON, urlencoded, and multipart bodies.</li>
79 <li>Tamper-proof signed cookies, suitable for authentication.</li>
80 <li>Body size limiting and file upload streaming to disc, to prevent
81 memory exhaustion attacks.</li>
82 <li>Serving of CSS, JavaScript, or whatever other static assets you want.</li>
83 <li>Logging, both ad-hoc logging and request logging, using a middleware.</li>
84 <li>Regular Gleam programming, so you can use any Gleam package you want
85 without trouble.</li>
86 </ul>
87 <p>
88 And a recommended project structure, so you can focus on solving the
89 problems you want to solve, rather than reinventing the wheel.
90 </p>
91 </section>
92
93 <section class="content-width">
94 <h2>That sounds good! What does it look like?</h2>
95 <p>
96 Here's a JSON API request handler that saves an item in a database.
97 </p>
98 <pre><code>import my_app/people
99import my_app/web.{Context}
100import gleam/result.{try}
101import wisp.{Request, Response}
102
103pub fn handle_request(req: Request, ctx: Context) -> Response {
104 use json <- wisp.require_json(req)
105
106 let result = {
107 use params <- try(people.parse_params(json))
108 use person <- try(people.save(params, ctx.db))
109 Ok(people.to_json(person))
110 }
111
112 case result {
113 Ok(body) -> wisp.json_response(body, 201)
114 Error(_) -> wisp.bad_request()
115 }
116}
117</code></pre>
118
119 <p>
120 Want to learn more? Check out <a href="https://github.com/lpil/wisp#learning-wisp">
121 the Wisp guides</a>.
122 </p>
123 </section>
124
125 <footer>
126 馃
127 <a href="https://github.com/gleam-lang/gleam/blob/main/CODE_OF_CONDUCT.md">Code of conduct</a>
128 </footer>
129</body>
130
131</html>