{"id":19881362,"url":"https://github.com/nike-inc/hal","last_synced_at":"2025-04-04T16:15:52.709Z","repository":{"id":33819913,"uuid":"162480428","full_name":"Nike-Inc/hal","owner":"Nike-Inc","description":"hal provides an AWS Lambda Custom Runtime environment for your Haskell applications.","archived":false,"fork":false,"pushed_at":"2023-12-19T04:16:38.000Z","size":409,"stargazers_count":235,"open_issues_count":16,"forks_count":13,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-14T09:45:24.080Z","etag":null,"topics":["aws","aws-lambda","aws-lambda-haskell","aws-lambda-runtime","bsd-license","haskell","haskell-library","library","nike"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Nike-Inc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-19T19:15:19.000Z","updated_at":"2024-08-14T00:34:17.107Z","dependencies_parsed_at":"2024-08-14T00:34:12.318Z","dependency_job_id":"e6e28a89-3eee-4518-86b0-abbdabeb9558","html_url":"https://github.com/Nike-Inc/hal","commit_stats":{"total_commits":300,"total_committers":11,"mean_commits":"27.272727272727273","dds":0.6333333333333333,"last_synced_commit":"ecf06eb07dd1bb813d2aea1c5bb6e0a541681616"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nike-Inc%2Fhal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nike-Inc%2Fhal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nike-Inc%2Fhal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nike-Inc%2Fhal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Nike-Inc","download_url":"https://codeload.github.com/Nike-Inc/hal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247208181,"owners_count":20901570,"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","aws-lambda-haskell","aws-lambda-runtime","bsd-license","haskell","haskell-library","library","nike"],"created_at":"2024-11-12T17:13:59.956Z","updated_at":"2025-04-04T16:15:52.689Z","avatar_url":"https://github.com/Nike-Inc.png","language":"Haskell","readme":"[![Stack Haskell Builds](https://github.com/Nike-Inc/hal/actions/workflows/haskell_stack.yaml/badge.svg)](https://github.com/Nike-Inc/hal/actions/workflows/haskell_stack.yaml)\n[![Cabal Haskell Builds](https://github.com/Nike-Inc/hal/actions/workflows/haskell_cabal.yaml/badge.svg)](https://github.com/Nike-Inc/hal/actions/workflows/haskell_cabal.yaml)\n\n# hal\n\nA runtime environment for [Haskell] applications running on [AWS Lambda].\n\n#### Flexible\n\nThis library uniquely supports different types of AWS Lambda Handlers for your needs/comfort with advanced Haskell.\nInstead of exposing a single function that constructs a Lambda, this library exposes many.\n\nFor lambdas that are pure and safe, then `pureRuntime` is ideal.\nIt accepts a handler with the signature `(FromJSON a, ToJSON b) =\u003e a -\u003e b`.\nThis runtime guarantees that side-effects cannot occur.\n\nFor advanced use cases `mRuntime` unlocks the full power of Monad Transformers.\nIt accepts handlers with the signature `(MonadCatch m, MonadIO m, FromJSON event, ToJSON result) =\u003e  (event -\u003e m result)`\nThis enables users to add caching logic or expose complex environments.\n\nWith numerous options in between these two, developers can choose the right balance of flexibility vs simplicity.\n\n#### Performant\n\nMeasuring lambda performance is tricky, so investigation and optimization is ongoing.\nCurrent indications show a _warm_ execution overhead of only ~20% more than the official [Rust Runtime] (a much lower level language).\n\n#### Robust\n\nWhile testing continues, we have executed over 30k test events without error caused by the runtime.\nNaive approaches lead to error rates well over 10%.\n\n## Table of Contents\n\n  - [Supported Platforms / GHC Versions](#supported-platforms-ghc-versions)\n  - [Quick Start](#quick-start)\n  - [Local Testing](#local-testing)\n\n## Supported Platforms / GHC Versions\n\nWe currently support this library under the same environment that [AWS Lambda\nsupports][lambda-env].\n\nOur [CI] currently targets the latest three [LTS Stackage Versions][stackage],\nthe latest three minor versions of [GHC] under [Cabal]\n(e.g. `8.6.x`, `8.4.x`, and `8.2.x`), and GHC-head / Stackage nightly builds.\n\nIf you haven't already, adding `docker: { enable: true }` to your `stack.yaml`\nfile will ensure that you're building a binary that can run in\n[AWS Lambda][lambda-env].\n\n## Quick Start\n\nThis quick start assumes you have the following tools installed:\n\n  - [Stack][stack.yaml]\n  - [Docker]\n  - [aws-cli]\n\nAdd `hal` to your [stack.yaml]'s [`extra-deps`] and enable\n[Docker] integration so that your binary is automatically compiled in a\ncompatible environment for AWS. Also add `hal` to your project's\ndependency list (either `project-name.cabal` or `package.yaml`)\n\n```yaml\n#...\nextra-deps:\n  - hal-${DESIRED_VERSION}\n# ...\ndocker:\n  enable: true\n# ...\n```\n\nThen, define your types and handler:\n\n```haskell\n{-# LANGUAGE DeriveGeneric  #-}\n{-# LANGUAGE NamedFieldPuns #-}\n\nmodule Main where\n\nimport AWS.Lambda.Runtime (pureRuntime)\nimport Data.Aeson         (FromJSON, ToJSON)\nimport GHC.Generics       (Generic)\n\ndata IdEvent  = IdEvent { input   :: String } deriving Generic\ninstance FromJSON IdEvent\n\ndata IdResult = IdResult { output :: String } deriving Generic\ninstance ToJSON IdResult\n\nhandler :: IdEvent -\u003e IdResult\nhandler IdEvent { input } = IdResult { output = input }\n\nmain :: IO ()\nmain = pureRuntime handler\n```\n\nYour binary should be called `bootstrap` in order for the custom runtime\nto execute properly:\n\n```yaml\n# Example snippet of package.yaml\n# ...\nexecutables:\n  bootstrap:\n    source-dirs: src\n    main: Main.hs  # e.g. {project root}/src/Main.hs\n# ...\n```\n\nYou'll need to either build on a compatible linux host or inside a compatible docker container (or some other mechanism like nix).\nNote that current Stack LTS images are _not_ compatible.\nIf you see an error message that contains \"version 'GLIBC_X.XX' not found\" when running (hosted or locally), then your build environment is not compatible.\n\nEnable stack's docker integration and define an optional image within stack.yaml:\n\n```yaml\n# file: stack.yaml\ndocker:\n  enabled: true\n  # If omitted, this defaults to fpco/stack-build:lts-${YOUR_LTS_VERSION}\n  image: ${BUILD_IMAGE}\n```\n\nDon't forget to define your [CloudFormation] stack:\n\n```yaml\n# file: template.yaml\nAWSTemplateFormatVersion: '2010-09-09'\nTransform: 'AWS::Serverless-2016-10-31'\nDescription: Test for the Haskell Runtime.\nResources:\n  HelloWorldApp:\n    Type: 'AWS::Serverless::Function'\n    Properties:\n      Handler: NOT_USED\n      Runtime: provided\n      # CodeUri is a relative path from the directory that this CloudFormation\n      # file is defined.\n      CodeUri: .stack-work/docker/_home/.local/bin/\n      Description: My Haskell runtime.\n      MemorySize: 128\n      Timeout: 3\n```\n\nFinally, build, upload and test your lambda!\n\n```bash\n# Build the binary, make sure your executable is named `bootstrap`\nstack build --copy-bins\n\n# Create your function package\naws cloudformation package \\\n  --template-file template.yaml \\\n  --s3-bucket your-existing-bucket \u003e \\\n  deployment_stack.yaml\n\n# Deploy your function\naws cloudformation deploy \\\n  --stack-name \"hello-world-haskell\" \\\n  --region us-west-2 \\\n  --capabilities CAPABILITY_IAM \\\n  --template-file deployment_stack.yaml\n\n# Take it for a spin!\naws lambda invoke \\\n  --function-name your-function-name \\\n  --region us-west-2 \\\n  --payload '{\"input\": \"foo\"}' \\\n  output.txt\n```\n\n## Local Testing\n\n### Dependencies\n\n  - [Stack][stack.yaml]\n  - [Docker]\n\n### Build\n\n```bash\ndocker pull fpco/stack-build:lts-{version} # First build only, find the latest version in stack.yaml\nstack build --copy-bins\n```\n\n### Execute w/ Docker\n\n```bash\necho '{ \"accountId\": \"byebye\" }' | docker run -i --rm \\\n    -e DOCKER_LAMBDA_USE_STDIN=1 \\\n    -v ${PWD}/.stack-work/docker/_home/.local/bin/:/var/task \\\n    lambci/lambda:provided\n```\n\n### Execute w/ SAM Local\n\nNote that hal currently only supports [aws-sam-cli] on versions \u003c1.0.\n\n```bash\necho '{ \"accountId\": \"byebye\" }' | sam local invoke --region us-east-1\n```\n\n[AWS Lambda]: https://docs.aws.amazon.com/lambda/latest/dg/welcome.html\n[Haskell]: https://www.haskell.org/\n[stack.yaml]: https://docs.haskellstack.org/\n[`extra-deps`]: https://docs.haskellstack.org/en/stable/yaml_configuration/#yaml-configuration\n[Docker]: https://www.docker.com/why-docker\n[aws-cli]: https://aws.amazon.com/cli/\n[CloudFormation]: https://aws.amazon.com/cloudformation/\n[aws-sam-cli]: https://github.com/awslabs/aws-sam-cli\n[Rust Runtime]: https://github.com/awslabs/aws-lambda-rust-runtime\n[lambda-env]: https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html\n[ci]: https://github.com/Nike-Inc/hal/actions\n[stackage]: https://www.stackage.org/\n[GHC]: https://www.haskell.org/ghc/download.html\n[Cabal]: https://www.haskell.org/cabal/download.html\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnike-inc%2Fhal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnike-inc%2Fhal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnike-inc%2Fhal/lists"}