{"id":15113852,"url":"https://github.com/jeamon/backend-api","last_synced_at":"2026-01-19T21:34:09.315Z","repository":{"id":64318631,"uuid":"511102361","full_name":"jeamon/backend-api","owner":"jeamon","description":"Demo of a fullscale Go-based RestFul API backend implementation with PostgreSQL and MongoDB as persistences layers.","archived":false,"fork":false,"pushed_at":"2023-08-05T10:12:13.000Z","size":99,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-03T16:58:25.366Z","etag":null,"topics":["api-rest","backend-api","bash-script","batch-script","ddd-architecture","docker","docker-compose","gin-framework","go","golang","mongodb","postgresql","ssl-certificates","uber-zap"],"latest_commit_sha":null,"homepage":"https://blog.cloudmentor-scale.com","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/jeamon.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2022-07-06T11:05:24.000Z","updated_at":"2023-08-05T09:55:34.000Z","dependencies_parsed_at":"2022-12-06T11:33:14.313Z","dependency_job_id":null,"html_url":"https://github.com/jeamon/backend-api","commit_stats":null,"previous_names":["jeamon/backend-api","jeamon/sample-rest-api"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jeamon/backend-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fbackend-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fbackend-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fbackend-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fbackend-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeamon","download_url":"https://codeload.github.com/jeamon/backend-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fbackend-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28585524,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T20:45:59.482Z","status":"ssl_error","status_checked_at":"2026-01-19T20:45:41.500Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["api-rest","backend-api","bash-script","batch-script","ddd-architecture","docker","docker-compose","gin-framework","go","golang","mongodb","postgresql","ssl-certificates","uber-zap"],"created_at":"2024-09-26T01:23:33.528Z","updated_at":"2026-01-19T21:34:09.294Z","avatar_url":"https://github.com/jeamon.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# backend-api\n\nThis is a demonstration of a go-based backend service which exposes RESTFUL APIs allowing to perform CRUD operations on data representing repositories scanning informations collected by a dedicated client tool. It basically shows how to design and implement a clean RestFul API backend with Go while using its built-in functionnality like interfaces for more flexibility \u0026 scalability. The storage layer is designed to support SQL \u0026 NoSQL datbases. Implementation has been done for PostgreSQL and MongoDB. Based on the code design, you can easily define or swap the wanted database (PostgreSQL or MongoDB) from the configuration file. A fake mocked database interface called mockdb was also added for live unit testing of the CRUD endpoints. The endpoint listens only on HTTPS and a bash script is available to generate self-signed tls/ssl certificates with openssl. The whole build process is automate when using docker-compose.\n\n\n## Get-Started\n\nThis project could be built \u0026 run with docker-compose quickly. You can even use Make Tool for common tasks (check Makefile for available commands).\nOtherwise, you can spin up the required database containers with the same docker-compose file and manually run separetely the backend api service.\n\n* First Method\n\n\t* Clone the repository\n\n\t\t```shell\n\t\t$ git clone https://github.com/jeamon/backend-api.git\n\t\t$ cd backend-api\n\t\t```\n\n\t* Build and Run with docker :\n\n\t\t```\n\t\t$ make run-docker\n\t\t```\n\n\t* Run locally after setting up the database :\n\n\t\t```\n\t\t$ make run-local\n\t\t```\n\n\t* Connect to the server :\n\n\t\t```\n\t\t$ https://\u003cserver-address\u003e:8080/api/v1/\u003cendpoint\u003e\n\t\t```\n\n\n* Second Method\n\n\t* Clone the repository\n\n\t\t```shell\n\t\t$ git clone https://github.com/jeamon/backend-api.git\n\t\t$ cd backend-api\n\t\t```\n\n\t* Build and Run with docker :\n\n\t\t```\n\t\t$ docker-compose up -d\n\t\t```\n\n\t* Connect to the server :\n\n\t\t```\n\t\t$ https://\u003cserver-address\u003e:8080/api/v1/\u003cendpoint\u003e\n\t\t```\n\n* Third Method\n\n\t* Clone the repository\n\n\t\t```shell\n\t\t$ git clone https://github.com/jeamon/backend-api.git\n\t\t$ cd backend-api\n\t\t```\n\n\t* Start all databases or the one set into the configs file :\n\t\t\n\t\t```\n\t\t$ docker-compose up -d postgres mongo pgadmin\n\t\t```\n\n\t* Create new certificates (update the CN with your server address) and place them under assets/certs folder.\n\n\t\t```shell\n\t\t$ openssl req -new -subj \"/CN=localhost\" -newkey rsa:2048 -nodes -keyout ./server.key -out ./server.csr\n\t\t$ openssl x509 -req -days 3650 -in ./server.csr -signkey ./server.key -out ./server.crt\n\t\t```\n\n\t\tor (run the script to automatically generate them and move them under assets/certs folder)\n\n\t\t```\n\t\t$ chmod +x ./scripts/generate.certs.sh\n\t\t$ ./scripts/generate.certs.sh\n\t\t```\n\n\t\tor (for testing purpose, rename existing tests certificates)\n\n\t\t```\n\t\t$ cp ./assets/certs/test.server.crt ./assets/certs/server.crt\n\t\t$ cp ./assets/certs/test.server.key ./assets/certs/server.key\n\t\t```\n\n\t* Set the configs file with the database address and Run the server.\n\t\t\t\t\n\t\t```\n\t\t$ go run main.go\n\t\t```\n\n\t\tor (below to fill the build flags : latest git hash and tag ID)\n\n\t\t```\n\t\t$ go run -ldflags \"-X 'main.GitCommit=$(git rev-list -1 HEAD)' -X 'main.GitTag=$(git describe --tags --abbrev=0)'\" main.go\n\t\t```\n\t\n* Connect to the pgadmin for managing the postgres database with UI.\n\t\n\t```\n\thttp://\u003cserver-address\u003e:8081/browser\n\t```\n\n\n## Credentials and Settings\t\n\t\nThe file **\u003cserver.config.yml\u003e** contains configurations settings of the server and the databases (postgresql and mongodb). It is loaded at server startup.\nThe file **\u003cserver.config.docker.yml\u003e** contains configurations settings of the server and the databases (postgresql and mongodb) but it is customized to be used when building and running the project with docker-compose.\n\n\n\n## Data structure of a scan infos object\n\nThis below structure is the core model of a scan infos and its representation into different format (json, bson, sql database). \n\n```go\ntype ScanInfos struct {\n\tID string `db:\"id\" json:\"id\" bson:\"id\" binding:\"required\"`\n\n\tCompanyID string `db:\"company_id\" json:\"company_id\" bson:\"company_id\" binding:\"required\"`\n\tUsername  string `db:\"username\" json:\"username\" bson:\"username\" binding:\"required\"`\n\n\tClientID string `db:\"client_id\" json:\"client_id\" bson:\"client_id\" binding:\"required\"`\n\n\tRepositoryURL string `db:\"repository_url\" json:\"repository_url\" bson:\"repository_url\" binding:\"required\"`\n\tCommitID      string `db:\"commit_id\" json:\"commit_id\" bson:\"commit_id\" binding:\"required\"`\n\tTagID         string `db:\"tag_id\" json:\"tag_id\" bson:\"tag_id\" binding:\"required\"`\n\n\tResults []string `db:\"results\" json:\"results\" bson:\"results\" binding:\"required\"`\n\n\tStartedAt   int64 `db:\"started_at\" json:\"started_at\" bson:\"started_at\" binding:\"required\"`\n\tCompletedAt int64 `db:\"completed_at\" json:\"completed_at\" bson:\"completed_at\" binding:\"required\"`\n\tSentAt      int64     `db:\"sent_at\" json:\"sent_at\" bson:\"sent_at\" binding:\"required\"`\n\tCreatedAt   time.Time `db:\"created_at\" json:\"-\" bson:\"created_at\"`\n\tUpdatedAt   time.Time `db:\"updated_at\" json:\"-\" bson:\"updated_at\"`\n\n\tError    string `db:\"error\" json:\"error\" bson:\"error\"`\n\tMetadata map[string]interface{} `db:\"metadata\" json:\"metadata\" bson:\"metadata\" binding:\"required\"`\n}\n```\n\nThe fields **\u003cstarted_at\u003e** **\u003ccompleted_at\u003e** and **\u003csent_at\u003e** hold the corresponding value in unix epoch time (in seconds).\nThe field **\u003cMetadata\u003e** is provided to hold more data if needed. This proactively provides a flexibility into the data structure.\n\n\n## Endpoints for CRUD Operations\n\n*By default the server runs on localhost (127.0.0.1) and listen on port 8080.*\n\n* Submit a performed scan information\n\n```\n[POST] http://\u003cserver-address\u003e:\u003cserver-port\u003e/api/v1/scaninfos\n```\n\n\n* Fetch specific scan information based on its id\n\n```\n[GET] http://\u003cserver-address\u003e:\u003cserver-port\u003e/api/v1/scaninfos/\u003cscan-id\u003e\n```\n\n\n* Display all available scan information\n\n```\n[GET] http://\u003cserver-address\u003e:\u003cserver-port\u003e/api/v1/scaninfos\n```\n\n* Update existing scan information\n\n```\n[PUT] http://\u003cserver-address\u003e:\u003cserver-port\u003e/api/v1/scaninfos\n```\n\n* Delete existing scan information from the database\n\n```\n[DELETE] http://\u003cserver-address\u003e:\u003cserver-port\u003e/api/v1/scaninfos/\u003cscan-id\u003e\n```\n\n\n## Others Endpoints\n\n* Quick check of the backend service availability\n\n```\n[GET] http://\u003cserver-address\u003e:\u003cserver-port\u003e/ping\n```\n\n* Health check of the global backend system\n\n```\n[GET] http://\u003cserver-address\u003e:\u003cserver-port\u003e/status\n```\n\n\n## POST [Request Body]\n\nBelow is the internal structure used to hold request body when submitting a new scan information.\n\n```go\ntype StoreScanInfosRequest struct {\n\tCompanyID string `json:\"company_id\" binding:\"required\"`\n\tUsername  string `json:\"username\" binding:\"required\"`\n\n\tClientID string `json:\"client_id\" binding:\"required\"`\n\n\tRepositoryUrl string `json:\"repository_url\" binding:\"required\"`\n\tCommitID      string `json:\"commit_id\" binding:\"required\"`\n\tTagID         string `json:\"tag_id\" binding:\"required\"`\n\n\tResults []string `json:\"results\" binding:\"required\"`\n\n\tStartedAt   int64 `json:\"started_at\" binding:\"required\"`\n\tCompletedAt int64 `json:\"completed_at\" binding:\"required\"`\n\tSentAt      int64     `json:\"sent_at\" binding:\"required\"`\n\n\tError    string `json:\"error\"`\n\tMetadata string `json:\"metadata\" binding:\"required\"`\n}\n```\n\nThe request body should be sent as JSON data. The fields **\u003cstarted_at\u003e** **\u003ccompleted_at\u003e** and **\u003csent_at\u003e** are the corresponding unix epoch time (in seconds).\n\n\n* Sample JSON data for POST request body\n\n```json\n{\n    \"company_id\": \"company-id\",\n    \"username\": \"jeamon\",\n    \"client_id\": \"vx.y.z\",\n    \"repository_url\": \"https://github.com/jeamon/backend-api\",\n    \"commit_id\": \"d7b8ff1412ebfcde26f9ddfdf9608d1525647958\",\n    \"tag_id\": \"v1.0.0\",\n    \"results\": [\"found something x\", \"found something y\", \"found something z\"],\n    \"started_at\":1655903720,\n    \"completed_at\": 1655903723,\n    \"sent_at\": 1655903725,\n    \"error\": \"got an x exception during repository scanning\",\n    \"metadata\": {\n        \"os\": \"linux\",\n        \"languages\": [\"go\", \"bash\", \"html\"],\n        \"arch\": \"amd64\"\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeamon%2Fbackend-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeamon%2Fbackend-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeamon%2Fbackend-api/lists"}