{"id":14987695,"url":"https://github.com/5olitude/ecommerce","last_synced_at":"2025-10-20T08:21:31.906Z","repository":{"id":201741049,"uuid":"408539912","full_name":"5olitude/ecommerce","owner":"5olitude","description":"A fully functional Ecommerce API in GO GIN Framework and mongoDB  with JWT Authentication ","archived":false,"fork":false,"pushed_at":"2021-10-16T03:39:42.000Z","size":403,"stargazers_count":35,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T00:16:59.313Z","etag":null,"topics":["api","ecommerce","gin","gin-gonic","go","golang","gorm","hacktoberfest","hacktoberfest2021","hact","jwt","jwt-authentication","mongodb","mongodb-driver","orm","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/5olitude.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}},"created_at":"2021-09-20T17:33:51.000Z","updated_at":"2025-01-29T11:39:36.000Z","dependencies_parsed_at":"2024-06-04T15:15:58.939Z","dependency_job_id":null,"html_url":"https://github.com/5olitude/ecommerce","commit_stats":null,"previous_names":["5olitude/ecommerce"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5olitude%2Fecommerce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5olitude%2Fecommerce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5olitude%2Fecommerce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5olitude%2Fecommerce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/5olitude","download_url":"https://codeload.github.com/5olitude/ecommerce/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248497817,"owners_count":21113984,"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":["api","ecommerce","gin","gin-gonic","go","golang","gorm","hacktoberfest","hacktoberfest2021","hact","jwt","jwt-authentication","mongodb","mongodb-driver","orm","rest-api"],"created_at":"2024-09-24T14:15:11.796Z","updated_at":"2025-10-20T08:21:26.859Z","avatar_url":"https://github.com/5olitude.png","language":"Go","readme":"## **Fully functional ECOMMERCE API USING GIN FRAMEWORK AND MONGODB**\n\n\u003cimg src=\"https://github.com/5olitude/ecommerce/blob/main/rest.png\"  alt=\"drawing\" width=\"500\" height=\"300\"/\u003e\n\n-----**Initial Release v2.30** ⚠️Not tested the efficiency\n\n# project structure\n\n- **Ecommerce** 📁\n  - controllers 📁\n    - controllers.go📝\n  - database📁\n    - database.go📝\n  - middleware📁\n    - middleware.go📝\n  - models📁\n    - models.go📝\n  - routes📁\n    - routes.go📝\n  - tokens📁\n    - tokengen.go📝\n  - go.sum 📝\n  - main.go📝\n\nclone this repo and change into the directory ecommerce-main***\nmake sure go is installed in your system\nRun\n\n```bash\n# Start the mongodb container for local development\ndocker-compose up -d\ngo run main.go\n```\n\n#### ` Using Mongodb for small scale ecommerce industry is not a good idea instead use redis or mysql`\n\n## API FUNCTIONALITY CURRENTLY ADDED?\n\n- Signup 🔒\n- Login 🔒\n- Product listing General View 👀\n- Adding the products to DB\n- Sorting the products from DB using regex 👀\n- Adding the products to cart 🛒\n- Removing the Product from cart🛒\n- Viewing the items in cart with total price🛒💰\n- Adding the Home Address 🏠\n- Adding the Work Address 🏢\n- Editing the Address ✂️\n- Deleting the Adress 🗑️\n- Checkout the Items from Cart\n- Buy Now products💰\n\n#### future implementations?\n\n- Pagination 1\u003e\u003e2\u003e\u003e3\n- Admin Part\n- OAuth 2\n- etc\\*\\*\\*\n\n## Code At glance in Database(database.go)\n\nfirst we need to define the database , make sure the mongodb installed in your system.\nThe important thing we have to remember is we need to create a database with two collections , Two collections that for storing the user informations and the other for storing the product informations.We must have to configure the url and port of mongodb configured in your system\n\n```go\n// code example of url and port in databasetup.go\nmongo.NewClient(options.Client().ApplyURI(\"mongodb://localhost:27017\")) --port and url\n// code example of defining collection name\nvar collection *mongo.Collection = client.Database(\"Ecommerce\").Collection(CollectionName)\n```\n\nlike to know more about configurations visit: https://www.mongodb.com/blog/post/quick-start-golang-mongodb-starting-and-setup\n\n## Code At glance in models.go\n\nThis part defines us how should our database looks like, I think its not about programming skills, but if you have creativity and basic syntax ideas and have some ability to defines struct from creativity 90% of work completed.Before Jumping into other codes we should have a rough idea about our plan so its better to lookup into models .\n\n- We have to define a product first , having a unique id , name and price\n\n```go\ntype Product struct {\n  Product_ID   primitive.ObjectID `bson:\"_id\"`\n  Product_Name *string            `json:\"product_name\"`\n  Price        *uint64            `json:\"price\"`\n  Rating       *uint8             `json:\"rating\"`\n  Image        *string            `json:\"image\"`\n}\n```\n\n- We have to define an slice of array products where a user can store individual products\n\n```go\ntype ProductUser struct {\n  Product_ID   primitive.ObjectID `bson:\"_id\"`\n  Product_Name *string            `json:\"product_name\" bson:\"product_name\"`\n  Price        int                `json:\"price\"  bson:\"price\"`\n  Rating       *uint              `json:\"rating\" bson:\"rating\"`\n  Image        *string            `json:\"image\"  bson:\"image\"`\n}\n```\n\n- The next struct we have to define the Address\n\n```go\ntype Address struct {\n  Address_id primitive.ObjectID `bson:\"_id\"`\n  House      *string            `json:\"house_name\" bson:\"house_name\"`\n  Street     *string            `json:\"street_name\" bson:\"street_name\"`\n  City       *string            `json:\"city_name\" bson:\"city_name\"`\n  Pincode    *string            `json:\"pin_code\" bson:\"pin_code\"`\n}\n```\n\n- If the user has ordered something the struct look like the one in below, having an embedded struct inside a struct , here we define the ProductUser as a slice(A person can buy more than one product right?) and a payement struct to define Cash on delivery or digital payement\n\n```go\ntype Order struct {\n  Order_ID       primitive.ObjectID `bson:\"_id\"`\n  Order_Cart     []ProductUser      `json:\"order_list\"  bson:\"order_list\"`\n  Orderered_At   time.Time          `json:\"ordered_on\"  bson:\"ordered_on\"`\n  Price          int                `json:\"total_price\" bson:\"total_price\"`\n  Discount       *int               `json:\"discount\"    bson:\"discount\"`\n  Payment_Method Payment            `json:\"payment_method\" bson:\"payment_method\"`\n}\n```\n\nThe Payement struct is something look like this\n\n```go\ntype Payment struct {\n  Digital bool `json:\"digital\" bson:\"digital\"`\n  COD     bool `json:\"cod\"     bson:\"cod\"`\n}\n```\n\n**_we can define those structs as the simple fields or blocks (genrally known as documents and subdocuments in mongodb)in the user databse or the user struct_**\n\n- Finally in the user struct we are going to embedd the simple structs .The new fields in struct are ID, Name ,Email, Token etc\n\n```go\ntype User struct {\n  ID              primitive.ObjectID `json:\"_id\" bson:\"_id\"`\n  First_Name      *string            `json:\"first_name\" validate:\"required,min=2,max=30\"`\n  Last_Name       *string            `json:\"last_name\"  validate:\"required,min=2,max=30\"`\n  Password        *string `json:\"password\" validate:\"required,min=6\"`\n  Email           *string `json:\"email\" validate:\"email,required\"`\n  Phone           *string `json:\"phone\" validate:\"required\"`\n  Token           *string `json:\"token\"`\n  Refresh_Token   *string `josn:\"refresh_token\"`\n  Created_At      time.Time `json:\"created_at\"`\n  Updated_At      time.Time `json:\"updtaed_at\"`\n  User_ID         string `json:\"user_id\"`\n  UserCart        []ProductUser `json:\"usercart\" bson:\"usercart\"`\n  Address_Details []Address `json:\"address\" bson:\"address\"`\n  Order_Status    []Order `json:\"orders\" bson:\"orders\"`\n}\n```\n\n## Code At Glance in controllers.go\n\nThis file mainly describes about the token authentication process . We have used the JWT authentication from dgrijalwa but now the repository has changed . I have used the same implemtaion for signup and login from\nhttps://dev.to/joojodontoh/build-user-authentication-in-golang-with-jwt-and-mongodb-2igd , this blog is clear and precise about jwt auhentication rather than my explanation here.\n\n**_There is an important thing we have to remember when defining array struct the mongodb converts the array to a nil in document field_**\n\nSo to overcome this problem we make an empty array in signup function like this,whever a user calls the signup function it initialise the documents to empty array\n\n```go\nuser.UserCart  =   make([]models.ProductUser, 0)\nuser.Address_Details = make([]models.Address, 0)\nuser.Order_Status = make([]models.Order, 0)\n```\n\n- **SIGNUP FUNCTION API CALL (POST REQUEST)**\n\nhttp://localhost:8000/users/signup\n\n```json\n{\n  \"first_name\": \"Joseph\",\n  \"last_name\": \"Hermis\",\n  \"email\": \"joe@example.com\", // Use @example.com for email because that is it's purpose. See https://www.rfc-editor.org/rfc/rfc6761.html and https://www.rfc-editor.org/rfc/rfc2606.html\n  \"password\": \"unlucky\",\n  \"phone\": \"+1558426655\"\n}\n```\n\nResponse :\"Successfully Signed Up!!\"\n\n- **LOGIN FUNCTION API CALL (POST REQUEST)**\n\n  http://localhost:8000/users/login\n\n\n```json\n{\n  \"email\": \"joe@example.com\",\n  \"password\": \"unlucky\"\n}\n```\n\nresponse will be like this\n\n```json\n{\n  \"_id\": \"***********************\",\n  \"first_name\": \"joseph\",\n  \"last_name\": \"hermis\",\n  \"password\": \"$2a$14$UIYjkTfnFnhg4qhIfhtYnuK9qsBQifPKgu/WPZAYBaaN17j0eTQZa\",\n  \"email\": \"josephhermis@protonomail.com\",\n  \"phone\": \"+1558921455\",\n  \"token\": \"eyJc0Bwcm90b25vbWFpbC5jb20iLCJGaXJzdF9OYW1lIjoiam9zZXBoIiwiTGFzdF9OYW1lIjoiaGVybWlzIiwiVWlkIjoiNjE2MTRmNTM5ZjI5YmU5NDJiZDlkZjhlIiwiZXhwIjoxNjMzODUzNjUxfQ.NbcpVtPLJJqRF44OLwoanynoejsjdJb5_v2qB41SmB8\",\n  \"Refresh_Token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6IiIsIkZpcnLCJVaWQiOiIiLCJleHAiOjE2MzQzNzIwNTF9.ocpU8-0gCJsejmCeeEiL8DXhFcZsW7Z3OCN34HgIf2c\",\n  \"created_at\": \"2021-10-09T08:14:11Z\",\n  \"updtaed_at\": \"2021-10-09T08:14:11Z\",\n  \"user_id\": \"61614f539f29be942bd9df8e\",\n  \"usercart\": [],\n  \"address\": [],\n  \"orders\": []\n}\n```\n\nLogin Function call create an outlayer for our collection\n\n- **Admin add Product Function POST REQUEST**\n\n  **note this function is not seperated from normal user fixed soon for admin**\n\n  http://localhost:8000/admin/addproduct\n\n```json\n{\n  \"product_name\": \"laptop\",\n  \"price\": 300,\n  \"rating\": 10,\n  \"image\": \"1.jpg\"\n}\n```\n\nResponse : \"Successfully added our Product Admin!!\"\n\n- **View all the Products in db GET REQUEST**\n\n  pagination added soon in next release\n\n  http://localhost:8000/users/productview\n\nResponse\n\n```json\n[\n  {\n    \"Product_ID\": \"6153ff8edef2c3c0a02ae39a\",\n    \"product_name\": \"notepad\",\n    \"price\": 50,\n    \"rating\": 10,\n    \"image\": \"penc.jpg\"\n  },\n  {\n    \"Product_ID\": \"616152679f29be942bd9df8f\",\n    \"product_name\": \"laptop\",\n    \"price\": 300,\n    \"rating\": 10,\n    \"image\": \"1.jpg\"\n  },\n  {\n    \"Product_ID\": \"616152ee9f29be942bd9df90\",\n    \"product_name\": \"top\",\n    \"price\": 300,\n    \"rating\": 10,\n    \"image\": \"1.jpg\"\n  },\n  {\n    \"Product_ID\": \"616152fa9f29be942bd9df91\",\n    \"product_name\": \"table\",\n    \"price\": 300,\n    \"rating\": 10,\n    \"image\": \"1.jpg\"\n  },\n  {\n    \"Product_ID\": \"616153039f29be942bd9df92\",\n    \"product_name\": \"apple\",\n    \"price\": 300,\n    \"rating\": 10,\n    \"image\": \"1.jpg\"\n  }\n]\n```\n\n- **Search Product by regex function (GET REQUEST)**\n\ndefines the word search sorting\nhttp://localhost:8000/users/search?name=le\n\nresponse:\n\n```json\n[\n  {\n    \"Product_ID\": \"616152fa9f29be942bd9df91\",\n    \"product_name\": \"table\",\n    \"price\": 300,\n    \"rating\": 10,\n    \"image\": \"1.jpg\"\n  },\n  {\n    \"Product_ID\": \"616153039f29be942bd9df92\",\n    \"product_name\": \"apple\",\n    \"price\": 300,\n    \"rating\": 10,\n    \"image\": \"1.jpg\"\n  }\n]\n```\n\nThe corresponding Query to mongodb is **ProductCollection.Find(ctx, bson.M{\"product_name\": bson.M{\"$regex\": queryParam}})**\n\n- **Adding the Products to the Cart (GET REQUEST)**\n\n  http://localhost:8000/addtocart?id=xxxproduct_idxxx\u0026userID=xxxxxxuser_idxxxxxx\n\n  Corresponding mongodb query\n\n```go\nfilter := bson.D{primitive.E{Key: \"_id\", Value: id}}\nupdate := bson.D{{Key: \"$push\", Value: bson.D{primitive.E{Key: \"usercart\", Value: bson.D{{Key: \"$each\", Value: productcart}}}}}}\n_, err = UserCollection.UpdateOne(ctx, filter, update)\n```\n\n- **Removing Item From the Cart (GET REQUEST)**\n\n  http://localhost:8000/addtocart?id=xxxxxxx\u0026userID=xxxxxxxxxxxx\n\n  Corresponding mongodb query\n\n```go\nfilter := bson.D{primitive.E{Key: \"_id\", Value: usert_id}}\n\nupdate := bson.M{\"$pull\": bson.M{\"usercart\": bson.M{\"_id\": removed_id}}}\n_, err = UserCollection.UpdateMany(ctx, filter, update)\n```\n\n- **Listing the item in the users cart (GET REQUEST) and total price**\n\n  http://localhost:8000/listcart?id=xxxxxxuser_idxxxxxxxxxx\n\n  Corresponding Mongodb Query (WE are using the aggrgate operation to find sum)\n\n       filter_match := bson.D{{Key: \"$match\", Value: bson.D{primitive.E{Key: \"_id\", Value: usert_id}}}}\n      unwind := bson.D{{Key: \"$unwind\", Value: bson.D{primitive.E{Key: \"path\", Value: \"$usercart\"}}}}\n      grouping := bson.D{{Key: \"$group\", Value: bson.D{primitive.E{Key: \"_id\", Value: \"$_id\"}, {Key: \"total\", Value: bson.D{primitive.E{Key: \"$sum\", Value: \"$usercart.price\"}}}}}}\n      pointcursor, err := UserCollection.Aggregate(ctx, mongo.Pipeline{filter_match, unwind, grouping})\n\n- **Addding the Address (POST REQUEST)**\n\n  http://localhost:8000/addadress?id=user_id**\\*\\***\\***\\*\\***\n\n  The Address array is limited to two values home and work address more than two address is not acceptable\n\n```json\n{\n  \"house_name\": \"jupyterlab\",\n  \"street_name\": \"notebook\",\n  \"city_name\": \"mars\",\n  \"pin_code\": \"685607\"\n}\n```\n\n- **Editing the Home Address(PUT REQUEST)**\n\n  http://localhost:8000/edithomeaddress?id=xxxxxxxxxxuser_idxxxxxxxxxxxxxxx\n\n- **Editing the Work Address(PUT REQUEST)**\n\n  http://localhost:8000/editworkaddress?id=xxxxxxxxxxuser_idxxxxxxxxxxxxxxx\n\n- **Delete Addresses(GET REQUEST)**\n\n  http://localhost:8000/deleteaddresses?id=xxxxxxxxxuser_idxxxxxxxxxxxxx\n\n  delete both addresses\n\n- **Cart Checkout Function and placing the order(GET REQUEST)**\n\n  After placing the order the items have to be deleted from cart functonality added\n\n  http://localhost:8000?id=xxuser_idxxx\n\n- **Instantly Buying the Products(GET REQUEST)**\n  http://localhost:8000?userid=xxuser_idxxx\u0026pid=xxxxproduct_idxxxx\n\n## Code At Glance in main.go\n\nAll the routes defined here requires the api authentication key\n\nRepo dedicting to my best friend mathappan 🐶 ,who left me without saying a goodbye and fill me with hopes even in my dark days RIP my friend\n\n#### Here are some of the reference I gone through while working on this project\n\nJWT Authentication using golang [^1]\n\nMongoDB Quick Introduction with Golang official blog [^2]\n\nPackage context instead of goroutine [^3]\n\nContext use cases in real scenarios [^4]\n\nMongo GO Driver official Documentation [^5]\n\nMongo Go official go documentation [^6]\n\nIs \"logout\" useless on a REST API? [^7]\n\nJWT AUTHENTICATION OFFICIAL [^8]\n\nGin framework Documentation [^9]\n\n[^1]: https://dev.to/joojodontoh/build-user-authentication-in-golang-with-jwt-and-mongodb-2igd\n[^2]: https://www.mongodb.com/blog/post/quick-start-golang-mongodb-starting-and-setup\n[^3]: https://pkg.go.dev/context\n[^4]: https://levelup.gitconnected.com/context-in-golang-98908f042a57\n[^5]: https://docs.mongodb.com/drivers/go/current/\n[^6]: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo\n[^7]: https://stackoverflow.com/questions/36294359/is-logout-useless-on-a-rest-api\n[^8]: github.com/golang-jwt/jwt\n[^9]: https://github.com/gin-gonic/gin\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5olitude%2Fecommerce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F5olitude%2Fecommerce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5olitude%2Fecommerce/lists"}