{"id":15288116,"url":"https://github.com/seek-oss/serverless-haskell","last_synced_at":"2025-04-04T08:08:47.705Z","repository":{"id":37886984,"uuid":"114596116","full_name":"seek-oss/serverless-haskell","owner":"seek-oss","description":"Deploying Haskell applications to AWS Lambda with Serverless","archived":false,"fork":false,"pushed_at":"2024-01-08T06:08:15.000Z","size":2940,"stargazers_count":217,"open_issues_count":23,"forks_count":22,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-28T07:07:45.432Z","etag":null,"topics":["aws","aws-lambda","haskell","haskell-stack","serverless"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seek-oss.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-18T04:33:00.000Z","updated_at":"2024-12-20T02:43:43.000Z","dependencies_parsed_at":"2024-10-30T00:22:39.840Z","dependency_job_id":null,"html_url":"https://github.com/seek-oss/serverless-haskell","commit_stats":{"total_commits":499,"total_committers":15,"mean_commits":"33.266666666666666","dds":"0.14428857715430865","last_synced_commit":"256ccabfd3adfde3baca625d59c12a5bdb395ec1"},"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seek-oss%2Fserverless-haskell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seek-oss%2Fserverless-haskell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seek-oss%2Fserverless-haskell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seek-oss%2Fserverless-haskell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seek-oss","download_url":"https://codeload.github.com/seek-oss/serverless-haskell/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247142066,"owners_count":20890652,"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":["aws","aws-lambda","haskell","haskell-stack","serverless"],"created_at":"2024-09-30T15:44:10.213Z","updated_at":"2025-04-04T08:08:47.683Z","avatar_url":"https://github.com/seek-oss.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serverless Haskell\n\n![Build status](https://github.com/seek-oss/serverless-haskell/workflows/Build/badge.svg)\n[![Hackage](https://img.shields.io/hackage/v/serverless-haskell.svg)](https://hackage.haskell.org/package/serverless-haskell)\n[![Stackage LTS](https://www.stackage.org/package/serverless-haskell/badge/lts)](https://www.stackage.org/lts/package/serverless-haskell)\n[![Hackage dependencies](https://img.shields.io/hackage-deps/v/serverless-haskell.svg)](https://packdeps.haskellers.com/feed?needle=serverless-haskell)\n[![npm](https://img.shields.io/npm/v/serverless-haskell.svg)](https://www.npmjs.com/package/serverless-haskell)\n\nDeploying Haskell code onto [AWS Lambda] as native runtime using [Serverless].\n\n## Prerequisites\n\n* AWS account\n* [Stack]\n* [NPM]\n* [Docker]\n\n## Usage\n\nThere are two ways to start, either via the stack template, or directly modifying a project. You may want to use the manual approach as the template specifies a specific stack resolver as it needs to hardcode the `stack.yaml` file.\n\nIn either case, you will want to have [Serverless] installed, eg. `npm install -g serverless`.\n\n### Using the stack template\n\n* Create a [Stack] package for your code:\n\n  ```shell\n  stack new mypackage https://raw.githubusercontent.com/seek-oss/serverless-haskell/master/serverless-haskell.hsfiles\n  ```\n\n* Update the resolver in the `stack.yaml` file. This is hardcoded as the resolver number is not known at template interpolation time. You should pick either the latest resolver, or one you have used before and have thus prebuilt many of the core packages for.\n\n* Install the dependencies and build the project:\n\n  ```shell\n  cd mypackage\n  npm install\n  stack build\n  sls invoke local -f mypackage-func\n  ```\n\n  This should invoke serverless locally and display output once everything has built.\n\n### Manually\n\n* Create a [Stack] package for your code:\n\n  ```shell\n  stack new mypackage\n  ```\n\n  LTS 10-17 are supported, older versions are likely to work too but untested.\n\n* Initialise a Serverless project inside the Stack package directory and install\n  the `serverless-haskell` plugin:\n\n  ```shell\n  cd mypackage\n  npm init -y\n  npm install --save serverless serverless-haskell@x.y.z\n  ```\n\n  The version of the NPM package to install must match the version of the\n  Haskell package.\n\n* Create `serverless.yml` with the following contents:\n\n  ```yaml\n  service: myservice\n\n  provider:\n    name: aws\n    runtime: haskell\n\n  functions:\n    myfunc:\n      handler: mypackage.mypackage-exe\n      # Here, mypackage is the Haskell package name and mypackage-exe is the\n      # executable name as defined in the Cabal file. The handler field may be\n      # prefixed with a path of the form `dir1/.../dirn`, relative to\n      # `serverless.yml`, which points to the location where the Haskell\n      # package `mypackage` is defined. This prefix is not needed when the\n      # Stack project is defined at the same level as `serverless.yml`.\n\n  plugins:\n    - serverless-haskell\n  ```\n\n* Write your `main` function:\n\n  ```haskell\n  import qualified Data.Aeson as Aeson\n\n  import AWSLambda\n\n  main = lambdaMain handler\n\n  handler :: Aeson.Value -\u003e IO [Int]\n  handler evt = do\n    putStrLn \"This should go to logs\"\n    print evt\n    pure [1, 2, 3]\n  ```\n\n* Add `aeson` and `serverless-haskell` to `package.yaml`:\n\n  ```yaml\n  dependencies:\n  - base \u003e= 4.7 \u0026\u0026 \u003c 5\n  - aeson\n  - serverless-haskell\n  ```\n\n* Build and test locally using `sls invoke local`:\n\n  The `serverless-haskell` plugin will build the package using Stack. Note that\n  the first build can take a long time. Consider adding `export SLS_DEBUG=*` so\n  you can see what is happening.\n\n  ```\n  export SLS_DEBUG=*\n  sls invoke local -f myfunc\n  ```\n\n* Use `sls deploy` to deploy the executable to AWS Lambda.\n\n  The `serverless-haskell` plugin will build the package using Stack, then upload\n  it to AWS together with a JavaScript wrapper to pass the input and output\n  from/to AWS Lambda.\n\n  ```\n  export SLS_DEBUG=*\n  sls deploy\n  ```\n  You can test the function and see the invocation results with:\n\n  ```\n  sls invoke -f myfunc`\n  ```\n\n\n### API Gateway\n\nThis plugin supports handling API Gateway requests. Declare the HTTP events\nnormally in `serverless.yml` and use\n[AWSLambda.Events.APIGateway](https://hackage.haskell.org/package/serverless-haskell/docs/AWSLambda-Events-APIGateway.html)\nin the handler to process them.\n\n[Serverless Offline] can be used for local testing of API Gateway requests. You\nmust use `--useDocker` flag so that the native Haskell runtime works correctly.\n\nWhen using [Serverless Offline], make sure that the project directory is\nworld-readable, otherwise the started Docker container will be unable to access\nthe handlers and all invocations will return HTTP status 502.\n\n### Notes\n\n* Only AWS Lambda is supported at the moment. Other cloud providers would\n  require different JavaScript wrappers to be implemented.\n\nSee\n[AWSLambda](https://hackage.haskell.org/package/serverless-haskell/docs/AWSLambda.html)\nfor documentation, including additional options to control the deployment.\n\n## Development\n\n`master` branch is the stable version. It is normally released to Hackage once\nnew changes are merged via Git tags.\n\nThe package is also maintained in Stackage LTS, provided the dependencies are\nnot blocking it.\n\n### Testing\n\n* Haskell code is tested with Stack: `stack test`.\n* TypeScript code is linted with `eslint`.\n\n### Integration tests\n\nIntegration test verifies that the project can build and deploy a complete\nfunction to AWS, and it runs with expected functionality.\n\nIntegration test is only automatically run up to deployment due to the need for\nan AWS account. To run manually:\n\n* Ensure you have the required dependencies:\n  - `curl`\n  - [jq]\n  - [NPM]\n  - [`pkg-config`](pkg-config)\n  - `pwgen`\n  - [Stack]\n* Get an AWS account and add the access credentials into your shell environment.\n* Run `./integration-test/run.sh`. The exit code indicates success.\n* To verify just the packaging, without deployment, run\n  `./integration-test/run.sh --dry-run`.\n* By default, the integration test is run with the LTS specified in\n  `stack.yaml`. To specify a different series, use `RESOLVER_SERIES=lts-9`.\n* To avoid creating a temporary directory for every run, specify\n  `--no-clean-dir`. This can speed up repeated test runs, but does not guarantee\n  the same results as a clean test.\n\n### Releasing\n\n* Ensure you are on the `master` branch.\n* Ensure that all the changes are reflected in the changelog.\n* Run the integration tests.\n* Run `./bumpversion major|minor|patch`. This will increment the version number,\n  update the changelog, create and push the Git tag and the branch.\n* If you have released an LTS version, merge the version branch into `master`,\n  taking care of the conflicts around version numbers and changelog, and release\n  the latest version as well.\n\n[AWS Lambda]: https://aws.amazon.com/lambda/\n[Docker]: https://www.docker.com/\n[jq]: https://stedolan.github.io/jq/\n[NPM]: https://www.npmjs.com/\n[pkg-config]: https://www.freedesktop.org/wiki/Software/pkg-config/\n[Serverless]: https://serverless.com/framework/\n[Serverless Offline]: https://github.com/dherault/serverless-offline\n[Stack]: https://haskellstack.org\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseek-oss%2Fserverless-haskell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseek-oss%2Fserverless-haskell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseek-oss%2Fserverless-haskell/lists"}