- Infrastructure Architecture
- Convert H5 Keras Files into Graph Model
- Setup Project
- Backend API Documentation
- Firestore Database Structure
This project using graph model
to processing Machine Learning in the Backend, and to be able to do that we need to convert file formatted *.h5 keras files into graph model using this step below.
-
Clone Main Branch and install requirements module
$ # Clone Repository Main Branch $ git clone https://github.com/Batikan-App/batikan-backend-svc.git $ # Change directory into batikan-backend-svc $ cd batikan-backend-svc $ # Install requirements module $ pip install -r requirements.txt
-
Convert file formatted *.h5 into saved model
$ # Convert file *.h5 into tfjs $ # For Example: python tools/convert-rapi.py batikan_model.h5 batikan_saved_model $ python tools/convert-h5-to-saved-format.py <h5_file_format> <output_folder>
-
Convert saved model into graph model using
tensorflowjs_converter
$ # Convert saved model into graph model $ # For Example: tensorflowjs_converter --input_format=tf_saved_model --output_format=tfjs_graph_model batikan_saved_model batikan_tfjs_model $ tensorflowjs_converter --input_format=tf_saved_model --output_format=tfjs_graph_model <tfjs_model_folder> <output_folder>
Note
File model.json
can we find in the <output_folder>
after we convert tfjs_model into graph_model and If you want to use it in Google Cloud, you can upload it into cloud storage
after that you copy public url of file model.json
for using it.
This project can be run locally using npm on your Linux Host
using this step below.
-
Clone Project Repository in branch
backend-api
$ # Clone Repository Branch backend-api if you didn't yet clone the Main Branch $ # If you have already clone Main branch of this repository than you just need to run 'git checkout backend-api' instead $ $ git clone https://github.com/Batikan-App/batikan-backend-svc.git -b backend-api $ # Change directory into batikan-backend-svc $ cd batikan-backend-svc
-
Define
MODEL_URL
in file.env
that locate file Model ML that used.$ # Please replace <bucket_name> with your own Cloud Storage Bucket $ echo "MODEL_URL='https://storage.googleapis.com/<bucket_name>/model/model.json'" > .env $ # If you choose to use model.json locally so you can use file url like this $ # For Example: echo "MODEL_URL='file:///model/model.json'" > .env $ echo "MODEL_URL='file:///<location_to_file_model.json>'" > .env
-
Install NodeJS Project Modules that needed using
$ npm install
-
Run NodeJS Project
$ # Use this line below if you want to deploy it in Development Mode $ npm run start:dev $ # Use this line below if you want to deploy it in Production Mode $ npm run start
Wait until shown text
Server listening on port 3000
that tell the Backend is ready to use.
Note
If there any error due to connection Firestore, make sure to connect or give permission this Backend APP to the Firestore either login gcloud first if you run it locally or attach Service account into Cloud Run if you run it with Cloud Run.
This document provides information about API endpoints and their functionalities. This documentation focuses on Backend API of Batikan APP uses to GET, PUT, PATCH, POST, and DELETE data who consume by our Batikan Application.
- API format is JSON (be nice and include a
Content-type: application/json
header to your request) - This Backend API uses header
authorization
to identify sessions token, so make sure to fill up the header for make sure success request on all API Endpoint except for login and register process. - The databases that uses in this Backend API is default databases in firestore named
(default)
. If you use custom firestore database names, make sure to change code to fit your need.
Route | HTTP Method | Description |
---|---|---|
/api/auth/register | POST | Register a new user |
/api/auth/login | POST | Log in a user |
/api/auth/logout | POST | Log out a user |
/api/user/profile | GET | Get user profile information |
/api/user/profile | PUT | Update user profile information inc. password |
/api/batik | GET | Get all batik items |
/api/batik/{id} | GET | Get specific batik items by it's id |
/api/batik/search?q={keyword} | GET | Get batik items that match keyword |
/api/batik/origin?q={origin} | GET | Get batik items that match origin |
/api/user/cart | GET | Get user's all cart items |
/api/user/cart | POST | Add batik items into cart |
/api/user/cart | PATCH | Update user's cart items quantity |
/api/user/cart | DELETE | Delete user's cart |
/api/user/order | GET | Get user's all orders |
/api/user/order | POST | Add user's cart into order |
/api/user/order | PUT | Update user's order delivery status |
/api/batik/scan | POST | Perform scanning image to identify batik |
-
Register a new user
-
Endpoint:
/api/auth/register
-
Method:
POST
-
Body Parameters:
Field Type Description Constraints name
string
Full name of the user Required email
string
Email address of the user Required, must be a valid email phone
string
Phone number Required password
string
Password for the account Required verify_password
string
Password verification Required, must match password
-
Example Request:
{ "name": "Aldi Khan Sakti Alvayadi", "email": "aldialvayadi@example.com", "phone": "1234567890", "password": "inirahasia", "verify_password": "inirahasia" }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "User registered successfully" }
- Email account is already existed.
{ "status": "failed", "message": "Users email is already existed!" }
- Verify password wrong.
{ "status": "failed", "message": "Verify password is wrong!" }
- Successfull Response.
-
-
Log in a user
-
Endpoint:
/api/auth/login
-
Method:
POST
-
Body Parameters:
Field Type Description Constraints email
string
Email address of the user Required, must be a valid email password
string
Password for the account Required -
Example Request:
{ "email": "aldialvayadi@example.com", "password": "inirahasia" }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Login successful", "token": "af2508e6-1687-40a8-9abf-e478aec3dbcc" }
- Invalid credentials.
{ "status": "failed", "message": "Invalid credentials" }
- Successfull Response.
-
-
Log out a user
-
Endpoint:
/api/auth/logout
-
Method:
POST
-
Body Parameters:
none
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Logged out successfully" }
- Successfull Response.
-
-
Get user profile information
-
Endpoint:
/api/user/profile
-
Method:
GET
-
Body Parameters:
none
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
-
Successfull Response.
{ "status": "success", "data": { "name": "Aldi Khan Sakti Alvayadi", "email": "aldialvayadi@example.com", "phone": "1234567890" } }
-
User information not found.
{ "status": "failed", "message": "User not found" }
-
-
-
Update user profile inc. password
-
Endpoint:
/api/user/profile
-
Method:
PUT
-
Body Parameters:
Field Type Description Constraints name
string
Full name of the user Required email
string
Email address of the user Required, must be a valid email phone
string
Phone number Required password
string
Password for the account Optional verify_password
string
Password verification Required if password
also fill up -
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Request:
{ "name": "aksa", "email": "aldialvayadi@example.com", "phone": "123", "password": "ini", "verify_password": "ini", }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Profile updated successfully" }
- User information not found.
{ "status": "failed", "message": "User not found" }
- Successfull Response.
-
-
Get all batik items
-
Endpoint:
/api/batik
-
Method:
GET
-
Body Parameters:
none
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
- Successfull Response.
{ "status": "success", "data": [ { "id": "G9F53OHaHpNmDSJv4anr", "data": { "name": "Kawung", "img": "<public_url_image_in_cloud_storage>", "origin": "Yogyakarta", "price": 34000, "desc": "Batik Kawung adalah motif batik tradisional Jawa yang sangat khas. Motifnya berupa bulatan-bulatan yang menyerupai buah kawung (sejenis kelapa) yang disusun secara geometris. Pola ini melambangkan kesempurnaan, kesucian, dan keagungan. Batik kawung memiliki sejarah yang panjang dan erat kaitannya dengan kerajaan-kerajaan di Jawa. Motif ini tidak hanya indah secara visual, tetapi juga sarat akan makna filosofis yang mendalam.", "sold": 30, "stock": 70 } }, .... ] }
- Successfull Response.
-
-
Get specific batik items by Id
-
Endpoint:
/api/batik/{id}
-
Method:
GET
-
Body Parameters:
none
-
Example Request Endpoint:
/api/batik/G9F53OHaHpNmDSJv4anr
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
-
Successfull Response.
{ "status": "success", "data": [ { "id": "G9F53OHaHpNmDSJv4anr", "data": { "name": "Kawung", "img": "<public_url_image_in_cloud_storage>", "origin": "Yogyakarta", "price": 34000, "desc": "Batik Kawung adalah motif batik tradisional Jawa yang sangat khas. Motifnya berupa bulatan-bulatan yang menyerupai buah kawung (sejenis kelapa) yang disusun secara geometris. Pola ini melambangkan kesempurnaan, kesucian, dan keagungan. Batik kawung memiliki sejarah yang panjang dan erat kaitannya dengan kerajaan-kerajaan di Jawa. Motif ini tidak hanya indah secara visual, tetapi juga sarat akan makna filosofis yang mendalam.", "sold": 30, "stock": 70 } } ] }
-
Batik not found.
{ "status": "failed", "message": "Batik not found" }
-
-
-
Get batik items that match keyword
-
Endpoint:
/api/batik/search?q={keyword}
-
Method:
GET
-
Body Parameters:
none
-
Example Request Query Parameters:
/api/batik/search?q=Kawung
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
-
Successfull Response.
{ "status": "success", "data": [ { "id": "G9F53OHaHpNmDSJv4anr", "data": { "name": "Kawung", "img": "<public_url_image_in_cloud_storage>", "origin": "Yogyakarta", "price": 34000, "desc": "Batik Kawung adalah motif batik tradisional Jawa yang sangat khas. Motifnya berupa bulatan-bulatan yang menyerupai buah kawung (sejenis kelapa) yang disusun secara geometris. Pola ini melambangkan kesempurnaan, kesucian, dan keagungan. Batik kawung memiliki sejarah yang panjang dan erat kaitannya dengan kerajaan-kerajaan di Jawa. Motif ini tidak hanya indah secara visual, tetapi juga sarat akan makna filosofis yang mendalam.", "sold": 30, "stock": 70 } }, .... ] }
-
Query parameter not found.
{ "status": "failed", "message": "Query parameter is required" }
-
Data not found.
{ "status": "failed", "message": "No documents found with keyword \"Trantum\"" }
-
Process error while search data.
{ "status": "error", "message": "An error occurred while processing the request" }
-
-
-
Get batik items that match origin
-
Endpoint:
/api/batik/origin?q={origin}
-
Method:
GET
-
Body Parameters:
none
-
Example Request Query Parameters:
/api/batik/origin?q=Yogya
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
-
Successfull Response.
{ "status": "success", "data": [ { "id": "G9F53OHaHpNmDSJv4anr", "data": { "name": "Kawung", "img": "<public_url_image_in_cloud_storage>", "origin": "Yogyakarta", "price": 34000, "desc": "Batik Kawung adalah motif batik tradisional Jawa yang sangat khas. Motifnya berupa bulatan-bulatan yang menyerupai buah kawung (sejenis kelapa) yang disusun secara geometris. Pola ini melambangkan kesempurnaan, kesucian, dan keagungan. Batik kawung memiliki sejarah yang panjang dan erat kaitannya dengan kerajaan-kerajaan di Jawa. Motif ini tidak hanya indah secara visual, tetapi juga sarat akan makna filosofis yang mendalam.", "sold": 30, "stock": 70 } }, .... ] }
-
Query parameter not found.
{ "status": "failed", "message": "Query parameter is required" }
-
Data not found.
{ "status": "failed", "message": "No documents found with origin containing \"Amerika\"" }
-
Process error while search data.
{ "status": "error", "message": "An error occurred while processing the request" }
-
-
-
Get user's all cart items
-
Endpoint:
/api/user/cart
-
Method:
GET
-
Body Parameters:
none
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
- Successfull Response.
{ "status": "success", "data": { "id": "6d3660ad499ac6b1e55cf263b8c912a1", "cartItem": [ { "id": "G9F53OHaHpNmDSJv4anr", "name": "Kawung", "img": "<public_url_image_in_cloud_storage>", "quantity": 30, "price": 50000 } ], "totalPrice": 1500000 } }
- Successfull Response.
-
-
Add batik items into cart
-
Endpoint:
/api/user/cart
-
Method:
POST
-
Body Parameters:
Field Type Description Constraints itemId
string
ID of Batik items Required quantity
integer
Quantity of Batik items Required -
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Request:
{ "itemId": "G9F53OHaHpNmDSJv4anr", "quantity": 30 }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Item added to cart successfully", "cartId": "ca1ac7d8a0a8b8288f122ef36841b628" }
- Failed to add item into cart.
{ "status": "failed", "message": "Failed to add item to cart" }
- Successfull Response.
-
-
Update user's cart items quantity
-
Endpoint:
/api/user/cart
-
Method:
PATCH
-
Body Parameters:
Field Type Description Constraints itemId
string
ID of Batik items Required quantity
integer
Quantity of Batik items Required -
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Request:
{ "itemId": "G9F53OHaHpNmDSJv4anr", "quantity": 10 }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Item updated to cart successfully", }
- Failed to update item quantity.
{ "status": "failed", "message": "Failed to update item quantity" }
- Successfull Response.
-
-
Delete user's cart
-
Endpoint:
/api/user/cart
-
Method:
DELETE
-
Body Parameters:
none
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Cart successfully deleted", }
- Failed to delete cart.
{ "status": "failed", "message": "Failed to delete cart" }
- Successfull Response.
-
-
Get user's all orders
-
Endpoint:
/api/user/order
-
Method:
GET
-
Body Parameters:
none
-
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Response:
- Successfull Response.
{ "status": "success", "data": { "userId": "6d3660ad499ac6b1e55cf263b8c912a1", "orders": [ { "orderId": "TznPrqKGz0uqmlgs8Ydf", "createdAt": { "_seconds": 1732701505, "_nanoseconds": 465000000 }, "totalPayment": 1020000, "name": "Aldi Khan Sakti Alvayadi", "phone": "0812456987124", "address": "Jl. Kenangan", "status": "Delivered", "userId": "6d3660ad499ac6b1e55cf263b8c912a1", "updatedAt": { "_seconds": 1732701505, "_nanoseconds": 465000000 }, "items": [ { "name": "Kawung", "img": "<public_url_image_in_cloud_storage>", "quantity": 30, "price": 34000 } ] } ] } }
- Successfull Response.
-
-
Add user's cart into order
-
Endpoint:
/api/user/order
-
Method:
POST
-
Body Parameters:
Field Type Description Constraints name
string
Full name of the user Required phone
string
Phone number Required address
string
User delivery address Required, must be a valid email -
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Request:
{ "name": "Aldi Khan Sakti Alvayadi", "phone": "0812456987124", "address": "Jl. Kenangan" }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Order added successfully", "data": { "orderId": "TznPrqKGz0uqmlgs8Ydf", "totalPayment": 1020000 } }
- Successfull Response.
-
-
Update user's order delivery status
-
Endpoint:
/api/user/order
-
Method:
PUT
-
Body Parameters:
Field Type Description Constraints orderId
string
Order ID user Required status
string
Delivery status order Required -
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Request:
{ "orderId": "TznPrqKGz0uqmlgs8Ydf", "status": "Delivered" }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Order updated successfully", }
- Successfull Response.
-
- Scan batik image
-
Endpoint:
/api/batik/scan
-
Method:
POST
-
Body Parameters:
Field Type Description Constraints image
file
Photo image of Batik Required, maximum size of image is 1 MB -
Example HTTP Headers Authorization:
authorization: 8fae42a0-9a0c-4c9d-81e4-19417b409c2e
-
Example Request:
{ "image": <image_file> }
-
Example Response:
- Successfull Response.
{ "status": "success", "message": "Model is predicted successfully", "data": { "batikId": "rRsxZMgPOOIaLQz6RmwC", "confidence": "99.98%", "data": { "desc": "Motif utama dari batik ini adalah gambar awan yang bergulung-gulung, menyerupai awan mendung. Namun, awan yang digambarkan tidak selalu berwarna gelap dan suram, melainkan sering kali diwarnai cerah dan penuh harapan.", "origin": "Cirebon, Jawa Barat", "img": "<public_url_image_in_cloud_storage>", "name": "Mega Mendung", "price": 55000, "stock": 100, "sold": 0 } } }
- Successfull Response.
-
400 Bad Request
: Invalid input data.401 Unauthorized
: Missing or invalid authentication token.404 Not Found
: Resource not found.500 Internal Server Error
: Server encountered an error.
-
Server error
- Response Body
{ "status": "failed", "message": "Invalid request data" }
- Response Body
-
Token session is not provided
- Response Body
{ "status": "failed", "message": "Unauthorized" }
- Response Body
-
Token session is expired
{ "status": "failed", "message": "Session expired" }
-
Token session is invalid
{ "status": "failed", "message": "Invalid session" }
-
Insufficient stock items
{ "status": "failed", "message": "Insufficient stock for item {item_name}." }
-
Order ID that requested is not authorized
{ "status": "failed", "message": "Order ID is not authorized!" }
The backend uses Firestore as the database to store data. Below is an explanation of the collections, documents, and their fields.
- Description: Stores user information for authentication and profile management.
- Structure:
users (Collection) └── {userId} (Document) ├── id: string (Reference to `users/{userId}`) ├── name: string ├── email: string ├── phone: string └── password: string
- Description: Stores user session information for authorization.
- Structure:
sessions (Collection) └── {token} (Document) ├── id: string (Reference to `sessions/{token}`) ├── userId: string (Reference to `users/{userId}`) ├── created_at: timestamp └── expired_at: timestamp
- Description: Stores information about batik items.
- Structure:
batik (Collection) └── {batikId} (Document) ├── name: string ├── desc: string ├── origin: string ├── img: string ├── price: integer ├── sold: integer └── stock: integer
- Description: Stores carts made by users.
- Structure:
carts (Collection) └── {cartId} (Document) (Reference to `users/{userId}`) ├── createdAt: timestamp ├── totalPrice: integer └── items (Collection) └── {batikId} (Document) (Reference to `batik/{batikId}`) ├── img: string ├── name: string ├── price: integer └── quantity: integer
- Description: Stores orders made by users.
- Structure:
orders (Collection) └── {orderId} (Document) ├── userId: string (Reference to `users/{userId}`) ├── totalPrice: number ├── status: string ├── createdAt: timestamp ├── updatedAt: timestamp └── items (Collection) └── {batikId} (Document) (Reference to `batik/{batikId}`) ├── img: string ├── name: string ├── price: integer └── quantity: integer