{"id":31557254,"url":"https://github.com/starichkov/golang-simple-notes","last_synced_at":"2025-10-04T23:53:46.548Z","repository":{"id":293472337,"uuid":"984130211","full_name":"starichkov/golang-simple-notes","owner":"starichkov","description":"Simple notes app written in Go, with assitance from several AI coding agents to evaulate their capabilities - Cursor and JetBrains Junie","archived":false,"fork":false,"pushed_at":"2025-08-31T17:42:34.000Z","size":176,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-31T19:11:46.152Z","etag":null,"topics":["couchdb","database-agnostic","go","golang","grpc","grpc-go","mongodb","rest-api"],"latest_commit_sha":null,"homepage":"","language":"Go","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/starichkov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","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,"zenodo":null},"funding":{"github":["starichkov"],"ko_fi":"starichkov","buy_me_a_coffee":"starichkov"}},"created_at":"2025-05-15T12:49:52.000Z","updated_at":"2025-08-31T17:42:38.000Z","dependencies_parsed_at":"2025-06-02T11:27:03.909Z","dependency_job_id":"d7862aa4-7ed9-428a-8bd5-8096df255a98","html_url":"https://github.com/starichkov/golang-simple-notes","commit_stats":null,"previous_names":["starichkov/golang-simple-notes"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/starichkov/golang-simple-notes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starichkov%2Fgolang-simple-notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starichkov%2Fgolang-simple-notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starichkov%2Fgolang-simple-notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starichkov%2Fgolang-simple-notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/starichkov","download_url":"https://codeload.github.com/starichkov/golang-simple-notes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starichkov%2Fgolang-simple-notes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278391190,"owners_count":25978945,"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","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["couchdb","database-agnostic","go","golang","grpc","grpc-go","mongodb","rest-api"],"created_at":"2025-10-04T23:53:36.445Z","updated_at":"2025-10-04T23:53:46.542Z","avatar_url":"https://github.com/starichkov.png","language":"Go","readme":"[![Author](https://img.shields.io/badge/Author-Vadim%20Starichkov-blue?style=for-the-badge)](https://github.com/starichkov)\n[![GitHub License](https://img.shields.io/github/license/starichkov/golang-simple-notes?style=for-the-badge)](https://github.com/starichkov/golang-simple-notes/blob/main/LICENSE.md)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/starichkov/golang-simple-notes/build.yml?style=for-the-badge)](https://github.com/starichkov/golang-simple-notes/actions/workflows/build.yml)\n[![Codecov](https://img.shields.io/codecov/c/github/starichkov/golang-simple-notes?style=for-the-badge)](https://codecov.io/gh/starichkov/golang-simple-notes)\n\nNotes API: Golang with NoSQL Databases\n=\n\nA simple microservice for notes management with REST and gRPC APIs, with support for multiple storage backends.\n\n*This project is generated using JetBrains Junie and several other AI coding agents to evaluate agent capabilities.*\n\n## Features\n\n- REST API for CRUD operations on notes\n- gRPC API for CRUD operations on notes\n- Multiple storage backends:\n  - In-memory storage (for development/testing)\n  - CouchDB storage\n  - MongoDB storage\n- Storage-agnostic design\n- Docker and Docker Compose support for easy deployment\n\n## Prerequisites\n\n- Docker and Docker Compose\n- Go 1.24 or later (for local development)\n\n## Compilation\n\nTo compile the application, you can use the following command:\n\n```bash\n# helps to keep unnecessary dependencies out, which can indirectly reduce size of the binary\ngo mod tidy\ngo build -ldflags=\"-s -w\"\n```\n\nwhere:\n- removes the symbol table and debug info. `-s`\n- removes DWARF debugging information. `-w`\n\n## Running with Docker Compose\n\nThe easiest way to run the application is using Docker Compose, which will start both the API services and the databases:\n\n```bash\ndocker-compose up -d\n```\n\nThis will:\n1. Start a CouchDB instance with authentication\n2. Start a MongoDB instance with authentication\n3. Build and start two Notes API services:\n   - One connected to CouchDB\n   - One connected to MongoDB\n\nThe services will be available at:\n\n### CouchDB Version\n- REST API: http://localhost:8080/api/notes\n- gRPC API: localhost:8081\n- CouchDB: http://localhost:5984 (admin:password)\n\n### MongoDB Version\n- REST API: http://localhost:8082/api/notes\n- gRPC API: localhost:8083\n- MongoDB: mongodb://localhost:27017 (admin:password)\n\nYou can run just one of the services if you prefer:\n\n```bash\n# Run only the CouchDB version\ndocker-compose up -d couchdb notes-api-couchdb\n\n# Run only the MongoDB version\ndocker-compose up -d mongodb notes-api-mongodb\n```\n\nTo stop the services:\n\n```bash\ndocker-compose down\n```\n\nTo stop the services and remove the volumes:\n\n```bash\ndocker-compose down -v\n```\n\n## Running Locally\n\nYou can run the application locally with different storage backends:\n\n### Using In-Memory Storage\n\nThe simplest way to run the application is with in-memory storage (no database required):\n\n```bash\nexport STORAGE_TYPE=memory\ngo run main.go\n```\n\n### Using CouchDB\n\nTo use CouchDB, you need to have CouchDB running. You can start CouchDB using Docker:\n\n```bash\ndocker run -d -p 5984:5984 --name couchdb \\\n  -e COUCHDB_USER=admin \\\n  -e COUCHDB_PASSWORD=password \\\n  couchdb:3.4.3\n```\n\nThen, set the environment variables and run the application:\n\n```bash\nexport STORAGE_TYPE=couchdb\nexport COUCHDB_URL=http://admin:password@localhost:5984\nexport COUCHDB_DB=notes\ngo run main.go\n```\n\n### Using MongoDB\n\nTo use MongoDB, you need to have MongoDB running. You can start MongoDB using Docker:\n\n```bash\ndocker run -d -p 27017:27017 --name mongodb \\\n  -e MONGO_INITDB_ROOT_USERNAME=admin \\\n  -e MONGO_INITDB_ROOT_PASSWORD=password \\\n  mongo:7.0.23-jammy\n```\n\nThen, set the environment variables and run the application:\n\n```bash\nexport STORAGE_TYPE=mongodb\nexport MONGODB_URI=mongodb://admin:password@localhost:27017\nexport MONGODB_DB=notes\nexport MONGODB_COLLECTION=notes\ngo run main.go\n```\n\n## API Endpoints\n\n### REST API\n\n- `GET /api/notes` - List all notes\n- `GET /api/notes/{id}` - Get a note by ID\n- `POST /api/notes` - Create a new note\n- `PUT /api/notes/{id}` - Update a note\n- `DELETE /api/notes/{id}` - Delete a note\n\n### Example Requests\n\n#### Create a Note\n\n```bash\ncurl -X POST http://localhost:8080/api/notes \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"title\":\"My Note\",\"content\":\"This is the content of my note\"}'\n```\n\n#### Get All Notes\n\n```bash\ncurl http://localhost:8080/api/notes\n```\n\n#### Get a Note by ID\n\n```bash\ncurl http://localhost:8080/api/notes/{id}\n```\n\n#### Update a Note\n\n```bash\ncurl -X PUT http://localhost:8080/api/notes/{id} \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"title\":\"Updated Title\",\"content\":\"Updated content\"}'\n```\n\n#### Delete a Note\n\n```bash\ncurl -X DELETE http://localhost:8080/api/notes/{id}\n```\n\n## Architecture\n\nThe application follows a clean architecture approach with a storage-agnostic design:\n\n- `model` - Contains the domain model (Note)\n- `storage` - Contains the storage interface and implementations:\n  - `storage.go` - Defines the NoteStorage interface and in-memory implementation\n  - `couchdb.go` - CouchDB implementation of the NoteStorage interface using the Kivik library\n  - `mongodb.go` - MongoDB implementation of the NoteStorage interface\n- `rest` - Contains the REST API handlers\n- `grpc` - Contains the gRPC service implementation\n- `proto` - Contains the Protocol Buffers definitions\n\nThe storage-agnostic design allows the application to work with different storage backends without changing the core business logic. The NoteStorage interface abstracts away the details of how notes are stored and retrieved, making it easy to add new storage implementations.\n\n## Testing\n\nThe project includes comprehensive tests for all components:\n\n### Running Tests\n\nTo run all tests:\n\n```bash\ngo test ./...\n```\n\nTo run tests for a specific package:\n\n```bash\ngo test ./model\ngo test ./storage\ngo test ./rest\ngo test ./grpc\n```\n\nTo run tests without external dependencies (skipping integration tests):\n\n```bash\ngo test -short ./...\n```\n\n### Test Coverage\n\nThe tests cover:\n\n- **Model Tests**: Tests for the Note model and ID generation\n- **Storage Tests**: \n  - In-memory storage implementation\n  - MongoDB storage implementation (integration tests, requires MongoDB)\n  - CouchDB storage implementation (integration tests, requires CouchDB)\n- **REST API Tests**: Tests for all REST endpoints using a mock storage\n- **gRPC Service Tests**: Tests for all gRPC service methods using a mock storage\n\nThe integration tests for MongoDB and CouchDB are skipped when running with the `-short` flag, as they require actual database instances.\n\n### Continuous Integration\n\nThis project uses GitHub Actions for continuous integration. The workflow includes:\n\n- Building the application\n- Running unit tests\n- Running integration tests with code coverage reporting\n- Building the Docker image\n- Testing the application with Docker Compose\n\nThe workflow is defined in `.github/workflows/build.yml` and runs automatically on pushes to the main branch and pull requests.\n\nTo view the latest build status and test results, click on the build status badge at the top of this README or visit the [Actions tab](https://github.com/starichkov/golang-simple-notes/actions) in the GitHub repository.\n\n#### Code Coverage\n\nThe GitHub Actions workflow generates code coverage reports for the tests. These reports are available as artifacts in the workflow runs and can be downloaded to analyze test coverage.\n\nAdditionally, code coverage reports are automatically uploaded to [Codecov](https://codecov.io) for visualization and tracking of coverage trends over time.\n\n## Configuration\n\nThe application can be configured using environment variables:\n\n### General Configuration\n- `STORAGE_TYPE` - The type of storage to use: `memory`, `couchdb`, or `mongodb` (default: `memory`)\n\n### CouchDB Configuration\n- `COUCHDB_URL` - The URL of the CouchDB server (default: \"http://localhost:5984\")\n- `COUCHDB_DB` - The name of the CouchDB database (default: \"notes\")\n\n### MongoDB Configuration\n- `MONGODB_URI` - The URI of the MongoDB server (default: \"mongodb://localhost:27017\")\n- `MONGODB_DB` - The name of the MongoDB database (default: \"notes\")\n- `MONGODB_COLLECTION` - The name of the MongoDB collection (default: \"notes\")\n\n## 🧾 About TemplateTasks\n\nTemplateTasks is a developer-focused initiative by Vadim Starichkov, currently operated as sole proprietorship in Finland.  \nAll code is released under open-source licenses. Ownership may be transferred to a registered business entity in the future.\n\n## 📄 License \u0026 Attribution\n\nThis project is licensed under the **MIT License** — see the [LICENSE](LICENSE.md) file for details.\n\n### Using This Project?\n\nIf you use this code in your own projects, attribution is required under the MIT License:\n\n```\nBased on golang-simple-notes by Vadim Starichkov, TemplateTasks\n\nhttps://github.com/starichkov/golang-simple-notes\n```\n\n**Copyright © 2025 Vadim Starichkov, TemplateTasks**\n","funding_links":["https://github.com/sponsors/starichkov","https://ko-fi.com/starichkov","https://buymeacoffee.com/starichkov"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarichkov%2Fgolang-simple-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstarichkov%2Fgolang-simple-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarichkov%2Fgolang-simple-notes/lists"}