🧚 A practical web framework for Gleam

v0.12.0

Changed files
+37 -26
examples
3-working-with-json
5-using-a-database
6-serving-static-assets
8-working-with-cookies
utilities
tiny_database
+1
examples/3-working-with-json/gleam.toml
··· 9 9 gleam_json = "~> 0.6" 10 10 gleam_erlang = "~> 0.23" 11 11 mist = "~> 0.14" 12 + gleam_http = "~> 3.5" 12 13 13 14 [dev-dependencies] 14 15 gleeunit = "~> 1.0"
+1
examples/5-using-a-database/gleam.toml
··· 10 10 tiny_database = { path = "../utilities/tiny_database" } 11 11 gleam_erlang = "~> 0.23" 12 12 mist = "~> 0.14" 13 + gleam_http = "~> 3.5" 13 14 14 15 [dev-dependencies] 15 16 gleeunit = "~> 1.0"
+23 -15
examples/5-using-a-database/src/app/web/people.gleam
··· 2 2 import gleam/dynamic.{type Dynamic} 3 3 import gleam/http.{Get, Post} 4 4 import gleam/json 5 - import gleam/map 5 + import gleam/dict 6 6 import gleam/result.{try} 7 7 import tiny_database 8 8 import wisp.{type Request, type Response} ··· 41 41 use ids <- try(tiny_database.list(ctx.db)) 42 42 43 43 // Convert the ids into a JSON array of objects. 44 - Ok(json.to_string_builder(json.object([ 45 - #( 46 - "people", 47 - json.array(ids, fn(id) { json.object([#("id", json.string(id))]) }), 44 + Ok( 45 + json.to_string_builder( 46 + json.object([ 47 + #( 48 + "people", 49 + json.array(ids, fn(id) { json.object([#("id", json.string(id))]) }), 50 + ), 51 + ]), 48 52 ), 49 - ]))) 53 + ) 50 54 } 51 55 52 56 case result { ··· 88 92 use person <- try(read_from_database(ctx.db, id)) 89 93 90 94 // Construct a JSON payload with the person's details. 91 - Ok(json.to_string_builder(json.object([ 92 - #("id", json.string(id)), 93 - #("name", json.string(person.name)), 94 - #("favourite-colour", json.string(person.favourite_colour)), 95 - ]))) 95 + Ok( 96 + json.to_string_builder( 97 + json.object([ 98 + #("id", json.string(id)), 99 + #("name", json.string(person.name)), 100 + #("favourite-colour", json.string(person.favourite_colour)), 101 + ]), 102 + ), 103 + ) 96 104 } 97 105 98 106 // Return an appropriate response. ··· 123 131 person: Person, 124 132 ) -> Result(String, Nil) { 125 133 // In a real application you might use a database client with some SQL here. 126 - // Instead we create a simple map and save that. 134 + // Instead we create a simple dict and save that. 127 135 let data = 128 - map.from_list([ 136 + dict.from_list([ 129 137 #("name", person.name), 130 138 #("favourite-colour", person.favourite_colour), 131 139 ]) ··· 138 146 ) -> Result(Person, Nil) { 139 147 // In a real application you might use a database client with some SQL here. 140 148 use data <- try(tiny_database.read(db, id)) 141 - use name <- try(map.get(data, "name")) 142 - use favourite_colour <- try(map.get(data, "favourite-colour")) 149 + use name <- try(dict.get(data, "name")) 150 + use favourite_colour <- try(dict.get(data, "favourite-colour")) 143 151 Ok(Person(name, favourite_colour)) 144 152 }
+2 -2
examples/5-using-a-database/test/app_test.gleam
··· 12 12 gleeunit.main() 13 13 } 14 14 15 - fn with_context(test: fn(Context) -> t) -> t { 15 + fn with_context(testcase: fn(Context) -> t) -> t { 16 16 // Create a new database connection for this test 17 17 use db <- tiny_database.with_connection(app.data_directory) 18 18 ··· 21 21 let context = Context(db: db) 22 22 23 23 // Run the test with the context 24 - test(context) 24 + testcase(context) 25 25 } 26 26 27 27 pub fn get_unknown_test() {
+1
examples/6-serving-static-assets/gleam.toml
··· 8 8 wisp = { path = "../.." } 9 9 gleam_erlang = "~> 0.23" 10 10 mist = "~> 0.14" 11 + gleam_http = "~> 3.5" 11 12 12 13 [dev-dependencies] 13 14 gleeunit = "~> 1.0"
+1 -2
examples/6-serving-static-assets/src/app/router.gleam
··· 1 1 import wisp.{type Request, type Response} 2 2 import gleam/string_builder 3 - import gleam/http 4 3 import app/web.{type Context} 5 4 6 5 const html = "<!DOCTYPE html> ··· 18 17 " 19 18 20 19 pub fn handle_request(req: Request, ctx: Context) -> Response { 21 - use req <- web.middleware(req, ctx) 20 + use _req <- web.middleware(req, ctx) 22 21 wisp.html_response(string_builder.from_string(html), 200) 23 22 }
+2 -2
examples/6-serving-static-assets/test/app_test.gleam
··· 9 9 gleeunit.main() 10 10 } 11 11 12 - fn with_context(test: fn(Context) -> t) -> t { 12 + fn with_context(testcase: fn(Context) -> t) -> t { 13 13 // Create the context to use in tests 14 14 let context = Context(static_directory: app.static_directory()) 15 15 16 16 // Run the test with the context 17 - test(context) 17 + testcase(context) 18 18 } 19 19 20 20 pub fn get_home_page_test() {
+1
examples/8-working-with-cookies/gleam.toml
··· 9 9 gleam_crypto = "~> 1.0" 10 10 gleam_erlang = "~> 0.23" 11 11 mist = "~> 0.14" 12 + gleam_http = "~> 3.5" 12 13 13 14 [dev-dependencies] 14 15 gleeunit = "~> 1.0"
+5 -5
examples/utilities/tiny_database/src/tiny_database.gleam
··· 3 3 import ids/nanoid 4 4 import gleam/json 5 5 import gleam/list 6 - import gleam/map.{type Map} 6 + import gleam/dict.{type Dict} 7 7 import simplifile 8 8 9 9 pub opaque type Connection { ··· 41 41 42 42 pub fn insert( 43 43 connection: Connection, 44 - values: Map(String, String), 44 + values: Dict(String, String), 45 45 ) -> Result(String, Nil) { 46 46 let assert Ok(_) = simplifile.create_directory_all(connection.root) 47 47 let id = nanoid.generate() 48 48 let values = 49 49 values 50 - |> map.to_list 50 + |> dict.to_list 51 51 |> list.map(fn(pair) { #(pair.0, json.string(pair.1)) }) 52 52 let json = json.to_string(json.object(values)) 53 53 use _ <- result.try( ··· 60 60 pub fn read( 61 61 connection: Connection, 62 62 id: String, 63 - ) -> Result(Map(String, String), Nil) { 63 + ) -> Result(Dict(String, String), Nil) { 64 64 use data <- result.try( 65 65 simplifile.read(file_path(connection, id)) 66 66 |> result.nil_error, 67 67 ) 68 68 69 - let decoder = dynamic.map(dynamic.string, dynamic.string) 69 + let decoder = dynamic.dict(dynamic.string, dynamic.string) 70 70 71 71 use data <- result.try( 72 72 json.decode(data, decoder)