A fully functional Ecommerce API in GO GIN Framework and mongoDB with JWT Authentication

Fully functional ECOMMERCE API USING GIN FRAMEWORK AND MONGODB

drawing

-----Initial Release v2.30 ⚠️ Not tested the efficiency

project structure

  • Ecommerce πŸ“
    • controllers πŸ“
      • controllers.go πŸ“
    • database πŸ“
      • database.go πŸ“
    • middleware πŸ“
      • middleware.go πŸ“
    • models πŸ“
      • models.go πŸ“
    • routes πŸ“
      • routes.go πŸ“
    • tokens πŸ“
      • tokengen.go πŸ“
    • go.sum πŸ“
    • main.go πŸ“

clone this repo and change into the directory ecommerce-main*** make sure go is installed in your system Run

# Start the mongodb container for local development
docker-compose up -d
go run main.go

Using Mongodb for small scale ecommerce industry is not a good idea instead use redis or mysql

API FUNCTIONALITY CURRENTLY ADDED?

  • Signup πŸ”’
  • Login πŸ”’
  • Product listing General View πŸ‘€
  • Adding the products to DB
  • Sorting the products from DB using regex πŸ‘€
  • Adding the products to cart πŸ›’
  • Removing the Product from cart πŸ›’
  • Viewing the items in cart with total price πŸ›’ πŸ’°
  • Adding the Home Address 🏠
  • Adding the Work Address 🏒
  • Editing the Address βœ‚οΈ
  • Deleting the Adress πŸ—‘οΈ
  • Checkout the Items from Cart
  • Buy Now products πŸ’°

future implementations?

  • Pagination 1>>2>>3
  • Admin Part
  • OAuth 2
  • etc***

Code At glance in Database(database.go)

first we need to define the database , make sure the mongodb installed in your system. The 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

// code example of url and port in databasetup.go
mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) --port and url
// code example of defining collection name
var collection *mongo.Collection = client.Database("Ecommerce").Collection(CollectionName)

like to know more about configurations visit: https://www.mongodb.com/blog/post/quick-start-golang-mongodb-starting-and-setup

Code At glance in models.go

This 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 .

  • We have to define a product first , having a unique id , name and price
type Product struct {
  Product_ID   primitive.ObjectID `bson:"_id"`
  Product_Name *string            `json:"product_name"`
  Price        *uint64            `json:"price"`
  Rating       *uint8             `json:"rating"`
  Image        *string            `json:"image"`
}
  • We have to define an slice of array products where a user can store individual products
type ProductUser struct {
  Product_ID   primitive.ObjectID `bson:"_id"`
  Product_Name *string            `json:"product_name" bson:"product_name"`
  Price        int                `json:"price"  bson:"price"`
  Rating       *uint              `json:"rating" bson:"rating"`
  Image        *string            `json:"image"  bson:"image"`
}
  • The next struct we have to define the Address
type Address struct {
  Address_id primitive.ObjectID `bson:"_id"`
  House      *string            `json:"house_name" bson:"house_name"`
  Street     *string            `json:"street_name" bson:"street_name"`
  City       *string            `json:"city_name" bson:"city_name"`
  Pincode    *string            `json:"pin_code" bson:"pin_code"`
}
  • 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
type Order struct {
  Order_ID       primitive.ObjectID `bson:"_id"`
  Order_Cart     []ProductUser      `json:"order_list"  bson:"order_list"`
  Orderered_At   time.Time          `json:"ordered_on"  bson:"ordered_on"`
  Price          int                `json:"total_price" bson:"total_price"`
  Discount       *int               `json:"discount"    bson:"discount"`
  Payment_Method Payment            `json:"payment_method" bson:"payment_method"`
}

The Payement struct is something look like this

type Payment struct {
  Digital bool `json:"digital" bson:"digital"`
  COD     bool `json:"cod"     bson:"cod"`
}

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

  • Finally in the user struct we are going to embedd the simple structs .The new fields in struct are ID, Name ,Email, Token etc
type User struct {
  ID              primitive.ObjectID `json:"_id" bson:"_id"`
  First_Name      *string            `json:"first_name" validate:"required,min=2,max=30"`
  Last_Name       *string            `json:"last_name"  validate:"required,min=2,max=30"`
  Password        *string `json:"password" validate:"required,min=6"`
  Email           *string `json:"email" validate:"email,required"`
  Phone           *string `json:"phone" validate:"required"`
  Token           *string `json:"token"`
  Refresh_Token   *string `josn:"refresh_token"`
  Created_At      time.Time `json:"created_at"`
  Updated_At      time.Time `json:"updtaed_at"`
  User_ID         string `json:"user_id"`
  UserCart        []ProductUser `json:"usercart" bson:"usercart"`
  Address_Details []Address `json:"address" bson:"address"`
  Order_Status    []Order `json:"orders" bson:"orders"`
}

Code At Glance in controllers.go

This 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 https://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.

There is an important thing we have to remember when defining array struct the mongodb converts the array to a nil in document field

So 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

user.UserCart  =   make([]models.ProductUser, 0)
user.Address_Details = make([]models.Address, 0)
user.Order_Status = make([]models.Order, 0)
  • SIGNUP FUNCTION API CALL (POST REQUEST)

http://localhost:8000/users/signup

{
  "first_name": "Joseph",
  "last_name": "Hermis",
  "email": "[email protected]", // 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
  "password": "unlucky",
  "phone": "+1558426655"
}

Response :"Successfully Signed Up!!"

{
  "email": "[email protected]",
  "password": "unlucky"
}

response will be like this

{
  "_id": "***********************",
  "first_name": "joseph",
  "last_name": "hermis",
  "password": "$2a$14$UIYjkTfnFnhg4qhIfhtYnuK9qsBQifPKgu/WPZAYBaaN17j0eTQZa",
  "email": "[email protected]",
  "phone": "+1558921455",
  "token": "eyJc0Bwcm90b25vbWFpbC5jb20iLCJGaXJzdF9OYW1lIjoiam9zZXBoIiwiTGFzdF9OYW1lIjoiaGVybWlzIiwiVWlkIjoiNjE2MTRmNTM5ZjI5YmU5NDJiZDlkZjhlIiwiZXhwIjoxNjMzODUzNjUxfQ.NbcpVtPLJJqRF44OLwoanynoejsjdJb5_v2qB41SmB8",
  "Refresh_Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6IiIsIkZpcnLCJVaWQiOiIiLCJleHAiOjE2MzQzNzIwNTF9.ocpU8-0gCJsejmCeeEiL8DXhFcZsW7Z3OCN34HgIf2c",
  "created_at": "2021-10-09T08:14:11Z",
  "updtaed_at": "2021-10-09T08:14:11Z",
  "user_id": "61614f539f29be942bd9df8e",
  "usercart": [],
  "address": [],
  "orders": []
}

Login Function call create an outlayer for our collection

{
  "product_name": "laptop",
  "price": 300,
  "rating": 10,
  "image": "1.jpg"
}

Response : "Successfully added our Product Admin!!"

Response

[
  {
    "Product_ID": "6153ff8edef2c3c0a02ae39a",
    "product_name": "notepad",
    "price": 50,
    "rating": 10,
    "image": "penc.jpg"
  },
  {
    "Product_ID": "616152679f29be942bd9df8f",
    "product_name": "laptop",
    "price": 300,
    "rating": 10,
    "image": "1.jpg"
  },
  {
    "Product_ID": "616152ee9f29be942bd9df90",
    "product_name": "top",
    "price": 300,
    "rating": 10,
    "image": "1.jpg"
  },
  {
    "Product_ID": "616152fa9f29be942bd9df91",
    "product_name": "table",
    "price": 300,
    "rating": 10,
    "image": "1.jpg"
  },
  {
    "Product_ID": "616153039f29be942bd9df92",
    "product_name": "apple",
    "price": 300,
    "rating": 10,
    "image": "1.jpg"
  }
]
  • Search Product by regex function (GET REQUEST)

defines the word search sorting http://localhost:8000/users/search?name=le

response:

[
  {
    "Product_ID": "616152fa9f29be942bd9df91",
    "product_name": "table",
    "price": 300,
    "rating": 10,
    "image": "1.jpg"
  },
  {
    "Product_ID": "616153039f29be942bd9df92",
    "product_name": "apple",
    "price": 300,
    "rating": 10,
    "image": "1.jpg"
  }
]

The corresponding Query to mongodb is ProductCollection.Find(ctx, bson.M{"product_name": bson.M{"$regex": queryParam}})

filter := bson.D{primitive.E{Key: "_id", Value: id}}
update := bson.D{{Key: "$push", Value: bson.D{primitive.E{Key: "usercart", Value: bson.D{{Key: "$each", Value: productcart}}}}}}
_, err = UserCollection.UpdateOne(ctx, filter, update)
filter := bson.D{primitive.E{Key: "_id", Value: usert_id}}

update := bson.M{"$pull": bson.M{"usercart": bson.M{"_id": removed_id}}}
_, err = UserCollection.UpdateMany(ctx, filter, update)
  • Listing the item in the users cart (GET REQUEST) and total price

    http://localhost:8000/listcart?id=xxxxxxuser_idxxxxxxxxxx

    Corresponding Mongodb Query (WE are using the aggrgate operation to find sum)

     filter_match := bson.D{{Key: "$match", Value: bson.D{primitive.E{Key: "_id", Value: usert_id}}}}
    unwind := bson.D{{Key: "$unwind", Value: bson.D{primitive.E{Key: "path", Value: "$usercart"}}}}
    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"}}}}}}
    pointcursor, err := UserCollection.Aggregate(ctx, mongo.Pipeline{filter_match, unwind, grouping})
    
  • Addding the Address (POST REQUEST)

    http://localhost:8000/addadress?id=user_id**\*\***\***\*\***

    The Address array is limited to two values home and work address more than two address is not acceptable

{
  "house_name": "jupyterlab",
  "street_name": "notebook",
  "city_name": "mars",
  "pin_code": "685607"
}

Code At Glance in main.go

All the routes defined here requires the api authentication key

Repo 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

Here are some of the reference I gone through while working on this project

JWT Authentication using golang 1

MongoDB Quick Introduction with Golang official blog 2

Package context instead of goroutine 3

Context use cases in real scenarios 4

Mongo GO Driver official Documentation 5

Mongo Go official go documentation 6

Is "logout" useless on a REST API? 7

JWT AUTHENTICATION OFFICIAL 8

Gin framework Documentation 9

Footnotes

  1. https://dev.to/joojodontoh/build-user-authentication-in-golang-with-jwt-and-mongodb-2igd ↩

  2. https://www.mongodb.com/blog/post/quick-start-golang-mongodb-starting-and-setup ↩

  3. https://pkg.go.dev/context ↩

  4. https://levelup.gitconnected.com/context-in-golang-98908f042a57 ↩

  5. https://docs.mongodb.com/drivers/go/current/ ↩

  6. https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo ↩

  7. https://stackoverflow.com/questions/36294359/is-logout-useless-on-a-rest-api ↩

  8. github.com/golang-jwt/jwt ↩

  9. https://github.com/gin-gonic/gin ↩

Owner
Joseph Hermis
Constant
Joseph Hermis
Similar Resources

GIN Project starter with logger, jwt auth, and more

Yet Another Golang RESTfull API A quick story about this starter-kit So, when I tried to write my first golang project, especially for web api, I real

Nov 21, 2022

Go-service-gin - Simple Web api application developed in Golang and Gin

Simple Web api application developed in Golang and Gin Initial Tutorial URL http

Jan 4, 2022

Go-gin-ddd-cqrs - Clean api rest with Go, Gin and GORM

Go-gin-ddd-cqrs - Clean api rest with Go, Gin and GORM

GOLANG API REST Clean api rest with Go, Gin and GORM. Clean Architecture with DD

Oct 21, 2022

A checkout functionality for an ecommerce application

A checkout functionality for an ecommerce application

EcommerceApp Server A checkout functionality for an ecommerce application πŸ“– Made with Golang πŸš€ Installation and execution | Available Routes | How t

Nov 23, 2021

ecommerce Go, Mysql, Redis, Selenium.

ecommerce Go, Mysql, Redis, Selenium. To run locally Have docker & docker-compose installed on your operating system. cp .env.example .env && docker-c

Aug 31, 2022

Gin-easy-todo - golang 의 RESTful API ν”„λ ˆμž„μ›Œν¬ gin 을 ν™œμš©ν•΄ μ•„μ£Ό κ°„λ‹¨ν•œ Todo μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“€μ–΄λ³΄μž.

Gin-easy-todo - golang 의 RESTful API ν”„λ ˆμž„μ›Œν¬ gin 을 ν™œμš©ν•΄ μ•„μ£Ό κ°„λ‹¨ν•œ Todo μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“€μ–΄λ³΄μž.

λͺ©μ°¨ 1. μš”μ•½ 2. λͺ©ν‘œ 3. API λͺ©λ‘ 4. ν”„λ‘œμ νŠΈ ꡬ쑰 5. νŒ¨ν‚€μ§€ 별 κΈ°λŠ₯κ³Ό 관계 6. 사전 μž‘μ—… 6.1. DB, Table 생성 6.2. λͺ¨λ“ˆ 생성 6.3. νŒ¨ν‚€μ§€ λ‹€μš΄λ‘œλ“œ 7. Gin μž‘μ„± 7.1. λ°μ΄ν„°λ² μ΄μŠ€ μ„€μ • 7.2. ν…Œμ΄λΈ”, μŠ€ν‚€λ§ˆ μ •μ˜ 7.3.

Jan 2, 2022

Gin-boilerplate - Gin boilerplate preconfigured with basic rest api features

Gin Boilerplate Build apis with gin faster with this template Features Validatio

Jun 24, 2022

Echo-mongo-api - Simple Golang REST application with Echo Framework & MongoDB

Echo-mongo-api - Simple Golang REST application with Echo Framework & MongoDB

Feb 14, 2022

Fully serverless CAPTCHA API created with API Gateway, Lambda, Dynamodb and Go

Fully serverless CAPTCHA API created with API Gateway, Lambda, Dynamodb and Go

Fully serverless CAPTCHA API created with API Gateway, Lambda, Dynamodb and Go

Mar 4, 2022
Comments
  • Review

    Review

    I added a bunch of comments throughout your code. Sometimes I added example or fixed the mistakes with a comment on why it is a mistake. In total quite a bit of changes.

    Your markdown contained a lot of errors in the formatting of text. I used the Prettier - Code formatter extension in VSCode to clean it up a bit.

    The main problems in your project are global variables, hard coded config and your controller functions does way more then a controller should do. I refactored AddToCart() to use dependency inject to create a much cleaner implementation that fixes some of the issues. Still it could be way simpler.

    If you have any more questions about why I changed things you can ask them in this pull request and I'll do my best to answer them.

    Oh, I would also highly recommend that you add tests to your project. And also a linter like golangci-lint.

    Two burning question: why did you pick MongoDB and JWT as a beginning programmer? What was your reason for picking Gin instead of the http handler in the Go standard library or something more standard like gorilla/mux?

Go-gin-mongo-api - A backend RESTful API built using golang, gin and mongoDB

go-gin-mongo-API This is a RESTful backend API which is developed using the gola

Jul 19, 2022
Gin-errorhandling - Gin Error Handling Middleware is a middleware for the popular Gin framework

Gin Error Handling Middleware Gin Error Handling Middleware is a middleware for

Sep 19, 2022
Go (Golang) API REST with Gin FrameworkGo (Golang) API REST with Gin Framework

go-rest-api-aml-service Go (Golang) API REST with Gin Framework 1. Project Description Build REST APIs to support AML service with the support of exte

Nov 21, 2021
Ecommerce-api - Rest api of e-commerce web application
Ecommerce-api - Rest api of e-commerce web application

E-commerce Rest API Swagger documentation to test api Domain diagram

Jan 2, 2023
Simple control panel for Golang based on Gin framework and MongoDB
Simple control panel for Golang based on Gin framework and MongoDB

Summer panel Simple control panel for Golang based on Gin framework and MongoDB How To Install go install github.com/night-codes/summer/summerGen@late

Dec 16, 2022
GinGoExample - Implement rest api using gin and go and mongodb

GinGoExample Implement rest api using gin and go and mongodb Optimizations using Singlton pattern to avoid repetetive commiunication with mongodb . Fe

Mar 25, 2022
API desarrollada en Go (Golang) para modificar precios en una tienda eCommerce (Shopify)
API desarrollada en Go (Golang) para modificar precios en una tienda eCommerce (Shopify)

Go eCommerce API API para modificar precios de productos en una tienda eCommerce de Shopify. Instrucciones Ingresar a la tienda eCommerce. Seleccionar

Oct 1, 2021
This codebase was created to demonstrate a fully fledged fullstack application built with Golang/Echo including CRUD operations, authentication, routing, pagination, and more.
This codebase was created to demonstrate a fully fledged fullstack application built with Golang/Echo including CRUD operations, authentication, routing, pagination, and more.

This codebase was created to demonstrate a fully fledged fullstack application built with Golang/Echo including CRUD operations, authentication, routing, pagination, and more.

Jan 6, 2023
Gin-boilerplate - This repository contains boilerplate code of a REST service using Gin (golang) framework.

Boilerplate REST service using Gin web framework (golang) Introduction This repository contains a boilerplate REST API service using Gin web framework

Apr 28, 2022
Backend to project Dating App. Written in GO, utilising Gin. MongoDB, AWS S3 and SNS.

Dating API Backend to project Dating App. Written in GO, utilising Gin. MongoDB, AWS S3 and SNS. In order to run simply type "go run ." The API requir

Apr 12, 2022