{"id":19130656,"url":"https://github.com/davicedraz/serverless-visit-counter","last_synced_at":"2026-04-11T21:06:25.478Z","repository":{"id":125766535,"uuid":"369915916","full_name":"davicedraz/serverless-visit-counter","owner":"davicedraz","description":"Experimental Serverless Node.js Express API","archived":false,"fork":false,"pushed_at":"2021-05-24T17:30:53.000Z","size":633,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-01-03T11:12:51.752Z","etag":null,"topics":["aws-lambda","clean-architecture","dynamodb","nodejs","serverless"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"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/davicedraz.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-22T22:18:22.000Z","updated_at":"2021-05-24T18:02:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"e4f09fb1-cd88-422a-8c69-e8695dc4d82d","html_url":"https://github.com/davicedraz/serverless-visit-counter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davicedraz%2Fserverless-visit-counter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davicedraz%2Fserverless-visit-counter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davicedraz%2Fserverless-visit-counter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davicedraz%2Fserverless-visit-counter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davicedraz","download_url":"https://codeload.github.com/davicedraz/serverless-visit-counter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240206988,"owners_count":19765041,"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-lambda","clean-architecture","dynamodb","nodejs","serverless"],"created_at":"2024-11-09T06:12:14.853Z","updated_at":"2025-11-12T21:00:58.208Z","avatar_url":"https://github.com/davicedraz.png","language":"JavaScript","readme":"﻿## Serverless Node Express API\n\nThis project it is being developed to apply serverless concepts using Node.js, the [Serverless](https://www.serverless.com/) framework and AWS platform (Lambda functions).\n\nThis a simples API that communicates with the free service [CountAPI](https://countapi.xyz/). This API allows you to create simple numeric counters IaaS (Integer as a Service) and increment/decrement it. This counter will be used to store the number of hits from a website.\n\nAPI features:\n\n- [x] Increase the number of accesses\n- [x] Consult the number of accesses\n- [x] Create a user\n- [x] View a user's information\n- [ ] Increment the hit counter automatically when the site is visited\n- [ ] Create a new hit counter when a logged in user visits the site\n\n\n### Architecture\n\nThis project takes advantage of [Services Pattern](https://www.serverless.com/blog/serverless-architecture-code-patterns), where a single Lambda function can handle a few (~4) jobs that are usually related via a data model or a shared infrastructure dependency. In our example app, all operations on the Users data model are performed in a single Lambda function, and multiple HTTP endpoints are created for all CRUD operations.\n\nBenefits of Services Pattern:\n\n- This will result in less Lambda functions that you need to manage.\n- Some separation of concerns still exists.\n- Teams can still work autonomously.\n- Faster deployments.\n- Theoretically better performance. When multiple jobs are within a Lambda function, there is a higher likelihood that Lambda function will be called more regularly, which means the Lambda will stay warm and users will run into less cold-starts.\n\nDrawbacks of Services Pattern:\n\n- Debugging gets slightly more complicated, since the Lambda function is handling multiple jobs, and has different outcomes.\n- Requires creating a router to call the right logic based on the request method or endpoint.\n- Bigger function sizes due to putting multiple operations within the same Lambda function.\n\n![Architecture](https://github.com/davicedraz/serverless-visit-counter/blob/master/docs/images/SVC%20-%20v1.1.0.png?raw=true)\n\n\n### Project Structure\n\nWhen we consider DevOps frameworks like [serverless](https://www.serverless.com/) Framework, it expects to point each route to a separate Lambda function. But this project exposes one single function, `api`, in `serverless.yml` which is responsible for handling all incoming requests thanks to configured `http` events. To learn more about `http` event configuration options, please refer to [http event docs](https://www.serverless.com/framework/docs/providers/aws/events/apigateway/). As the events are configured in a way to accept all incoming requests, `express` framework is responsible for routing and handling requests internally. Implementation takes advantage of `serverless-http` package, which allows you to wrap existing `express` applications. To learn more about `serverless-http`, please refer to corresponding [GitHub repository](https://github.com/dougmoscrop/serverless-http). Additionally, it also handles provisioning of a DynamoDB database that is used for storing data about users. The `express` application exposes two endpoints, `POST /users` and `GET /user/{userId}`, which allow to create and retrieve users.\n\n\n### Deployment\n\nThis example is made to work with the Serverless Framework dashboard, which includes advanced features such as CI/CD, monitoring, metrics, etc.\n\nIn order to deploy with dashboard, you need to first login with:\n\n```\nserverless login\n```\n\ninstall dependencies with:\n\n```\nnpm install\n```\n\nand then perform deployment with:\n\n```\nserverless deploy\n```\n\nAfter running deploy, you should see output similar to:\n\n```bash\nServerless: Packaging service...\nServerless: Excluding development dependencies...\nServerless: Creating Stack...\nServerless: Checking Stack create progress...\n........\nServerless: Stack create finished...\nServerless: Uploading CloudFormation file to S3...\nServerless: Uploading artifacts...\nServerless: Uploading service aws-node-express-dynamodb-api.zip file to S3 (718.53 KB)...\nServerless: Validating template...\nServerless: Updating Stack...\nServerless: Checking Stack update progress...\n....................................\nServerless: Stack update finished...\nService Information\nservice: aws-node-express-dynamodb-api\nstage: dev\nregion: us-east-1\nstack: aws-node-express-dynamodb-api-dev\nresources: 13\napi keys:\n  None\nendpoints:\n  ANY - https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/\n  ANY - https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/{proxy+}\nfunctions:\n  api: aws-node-express-dynamodb-api-dev-api\nlayers:\n  None\n```\n\n### Local development\n\nIt is also possible to emulate DynamodB, API Gateway and Lambda locally by using `serverless-dynamodb-local` and `serverless-offline` plugins. In order to do that, execute the following commands:\n\n```bash\nserverless plugin install -n serverless-dynamodb-local\nserverless plugin install -n serverless-offline\n```\n\nIt will add both plugins to `devDependencies` in `package.json` file as well as will add it to `plugins` in `serverless.yml`. Make sure that `serverless-offline` is listed as last plugin in `plugins` section:\n\n```\nplugins:\n  - serverless-dynamodb-local\n  - serverless-offline\n```\n\nYou should also add the following config to `custom` section in `serverless.yml`:\n\n```\ncustom:\n  (...)\n  dynamodb:\n    start:\n      migrate: true\n    stages:\n      - dev\n```\n\n![DynamodB](https://github.com/davicedraz/serverless-visit-counter/blob/master/docs/images/local-dynamo-db.png?raw=true)\n\nAdditionally, we need to reconfigure `AWS.DynamoDB.DocumentClient` to connect to our local instance of DynamoDB. We can take advantage of `IS_OFFLINE` environment variable set by `serverless-offline` plugin and replace:\n\n```javascript\nconst dynamoDbClient = new AWS.DynamoDB.DocumentClient();\n```\n\nwith the following:\n\n```javascript\nconst dynamoDbClientParams = {};\nif (process.env.IS_OFFLINE) {\n  dynamoDbClientParams.region = 'localhost'\n  dynamoDbClientParams.endpoint = 'http://localhost:8000'\n}\nconst dynamoDbClient = new AWS.DynamoDB.DocumentClient(dynamoDbClientParams);\n```\n\nAfter that, running the following command with start both local API Gateway emulator as well as local instance of emulated DynamoDB:\n\n```bash\nserverless offline start\n```\n\nTo learn more about the capabilities of `serverless-offline` and `serverless-dynamodb-local`, please refer to their corresponding GitHub repositories:\n- https://github.com/dherault/serverless-offline\n- https://github.com/99x/serverless-dynamodb-local\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavicedraz%2Fserverless-visit-counter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavicedraz%2Fserverless-visit-counter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavicedraz%2Fserverless-visit-counter/lists"}