{"id":22062753,"url":"https://github.com/ryan-haskell/elm-graphql-server","last_synced_at":"2025-09-05T03:34:03.119Z","repository":{"id":42704671,"uuid":"471539257","full_name":"ryan-haskell/elm-graphql-server","owner":"ryan-haskell","description":"Create a GraphQL API with Elm!","archived":false,"fork":false,"pushed_at":"2023-03-31T20:44:49.000Z","size":543,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-11T23:52:39.804Z","etag":null,"topics":["apollo","backend","elm","graphql","sql"],"latest_commit_sha":null,"homepage":"","language":"Elm","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ryan-haskell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-18T22:59:28.000Z","updated_at":"2022-08-27T01:42:54.000Z","dependencies_parsed_at":"2022-09-02T06:02:33.653Z","dependency_job_id":null,"html_url":"https://github.com/ryan-haskell/elm-graphql-server","commit_stats":null,"previous_names":["ryan-haskell/elm-graphql-server"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryan-haskell%2Felm-graphql-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryan-haskell%2Felm-graphql-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryan-haskell%2Felm-graphql-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryan-haskell%2Felm-graphql-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryan-haskell","download_url":"https://codeload.github.com/ryan-haskell/elm-graphql-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253837406,"owners_count":21971982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apollo","backend","elm","graphql","sql"],"created_at":"2024-11-30T18:26:47.647Z","updated_at":"2025-05-12T23:03:05.923Z","avatar_url":"https://github.com/ryan-haskell.png","language":"Elm","readme":"# @ryannhg/elm-graphql-server\n\u003e Create a GraphQL API with Elm!\n\n![A screenshot of a demo query in the GraphQL playground](./screenshot.png)\n\n## Playing around locally\n\n_You'll need [Node.js](https://nodejs.org) to run this project on your local computer._\n\n```bash\nnpm start\n```\n\n- Visit http://localhost:4000 to use the GraphQL API\n- Mess with Elm files in `src/Resolvers` to change how the API responds\n\n## Overview\n\nThe server starts in a file called `src/index.js`. It is powered by an Elm program, compiled\nas a `Platform.worker`. That means you'll need to compile your Elm app first with `npm run elm:build`, or you can use the `npm run dev` script that automatically compiles things as you code!\n\nRight now, the API server doesn't do too much. It listens for GraphQL requests at `http://localhost:4000`, and sends that request information to our Elm worker, so we can handle our resolvers with Elm code.\n\nFor now, you can modify the GraphQL schema by editing `src/schema.gql`, and add a new resolver in `src/Worker.elm`.\n\nI have been making modules in `src/Resolvers` to organize the code, but that's just so you can easily follow what's going on!\n\nThis is not a production-ready thing, but I thought it would be a fun experiment to see what using the Elm language would be like for a backend GraphQL API.\n\nA real implementation would require a nice way to talk to a database, a third-party HTTP service, or do things like application logging– but for now this is all we have 🙂\n\n### Talking to a SQL Database\n\nI've been exploring communicating to a `sqlite` database. This project supports basic forms of:\n\n- [x] `SELECT` statements\n  - Example of `findOne` with the [`user` query](./src/Resolvers/Query/User.elm)\n  - Example of `findAll` with the [`users` query](./src/Resolvers/Query/Users.elm)\n- [x] `INSERT` statements\n  - Example of `insertOne` with the [`createUser` mutation](./src/Resolvers/Mutation/CreateUser.elm)\n- [x] `UPDATE` statements\n  - Example of `updateOne` with the [`updateUser` mutation](./src/Resolvers/Mutation/UpdateUser.elm)\n- [x] `DELETE` statements\n  - Example of `deleteOne` with the [`deleteUser` mutation](./src/Resolvers/Mutation/DeleteUser.elm)\n\n### Solving the N + 1 problem\n\nThis repo also features examples of queries that need to access data across multiple tables. For example, if a user creates a post, the database looks something like this:\n\n#### `users`\n\nid | username | avatarUrl\n--- | --- | ---\n1 | \"ryan\" | NULL\n\n#### `posts`\n\nid | caption | imageUrls\n--- | --- | ---\n3 | \"Elm conf 2019 was sweet!\" | [ ... ]\n\n\n#### `user_authored_post`\n\nid | postId | userId\n--- | --- | ---\n5 | 3 | 1\n\nA user of our GraphQL API might write a query like this, to get the `id` and `username` of the author of post #3:\n\n```graphql\nquery {\n  post(id: 3) {\n    id\n    caption\n    author {\n      id\n      username\n    }\n  }\n}\n```\n\nWhen this GraphQL query comes through [the Query.post resolver](./src/Resolvers/Query/Post.elm) runs a few SQL statements:\n\n```sql\n-- Get the data stored for that post\nSELECT id, caption FROM posts WHERE id = 3;\n```\n\n```sql\n-- Check the \"user_authored_post\" table for any authors\nSELECT userId FROM user_authored_post WHERE postId = 3;\n```\n\n```sql\n-- The last query found a row with userId = 1,\n-- so we pass that into the final SQL query that\n-- fetches the `id` and `username` for our author\nSELECT id, username FROM users WHERE id = 1;\n```\n\nIf we need 3 SQL statements for one post and its author, how does this work when fetching multiple posts?\n\n```graphql\nquery {\n  posts {\n    id\n    caption\n    author {\n      id\n      username\n    }\n  }\n}\n```\n\nThis GraphQL request will be sent to [our Query.posts resolver](./src/Resolvers/Query/Posts.elm), which lists the first 25 posts in the system. If we repeated the previous strategy for each of those posts– that would mean 3 * 25... 75 SQL queries!?\n\nLuckily for us, all our resolvers can access [an `info` argument for the GraphQL query](https://graphql.org/learn/execution/#root-fields-resolvers). This allows us to perform these queries in bulk– using a similar approach to Facebook's DataLoader! \n\nRather than making a query for each post, we use SQL's `IN` keyword to fetch author data for all 25 posts using only 3 SQL statements! (This would still only need 3 queries if we brought back 10, 100, or 1000 posts):\n\n```sql\n-- First, we ask for the first 25 posts\nSELECT id, caption FROM posts LIMIT 25;\n```\n\n```sql\n-- Now that we have all those posts, we use their IDs \n-- to query the `user_authored_post` table:\nSELECT postId, userId FROM user_authored_post WHERE postId IN ( 1, 2, 3, ... 25 );\n```\n\n```sql\n-- Once we have all those edges, we can use the userId column\n-- to do one final SQL query for the author data for all those author ids\nSELECT id, username FROM users WHERE id IN ( 1, 2, 3, 4, ... );\n```\n\nUsing this `WHERE id IN ...` strategy helps us avoid a common GraphQL pitfall called the [N + 1 problem](https://www.youtube.com/watch?v=ld2_AS4l19g). Try making nested queries, and see the SQL that is generated!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryan-haskell%2Felm-graphql-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryan-haskell%2Felm-graphql-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryan-haskell%2Felm-graphql-server/lists"}