Skip to content

Commit 1711e44

Browse files
[API]Add more enpoints to API (#2390)
* Add pagination to API * Add pagination to API
1 parent afe4af2 commit 1711e44

File tree

1 file changed

+283
-0
lines changed

1 file changed

+283
-0
lines changed

api/main.go

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"log"
1212
"net/http"
1313
"os"
14+
"strconv"
1415
"time"
1516

1617
"github.com/gorilla/mux"
@@ -31,6 +32,7 @@ func loadEnv() {
3132
}
3233
}
3334

35+
// DataModel represents a single document in MongoDB
3436
type DataModel struct {
3537
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
3638
CT_TYPE uint `json:"ct_type" bson:"ct_type"`
@@ -56,6 +58,13 @@ type StatusModel struct {
5658
STATUS string `json:"status" bson:"status"`
5759
}
5860

61+
type CountResponse struct {
62+
TotalEntries int64 `json:"total_entries"`
63+
StatusCount map[string]int64 `json:"status_count"`
64+
NSAPPCount map[string]int64 `json:"nsapp_count"`
65+
}
66+
67+
// ConnectDatabase initializes the MongoDB connection
5968
func ConnectDatabase() {
6069
loadEnv()
6170

@@ -78,6 +87,7 @@ func ConnectDatabase() {
7887
fmt.Println("Connected to MongoDB on 10.10.10.18")
7988
}
8089

90+
// UploadJSON handles API requests and stores data as a document in MongoDB
8191
func UploadJSON(w http.ResponseWriter, r *http.Request) {
8292
var input DataModel
8393

@@ -98,6 +108,7 @@ func UploadJSON(w http.ResponseWriter, r *http.Request) {
98108
json.NewEncoder(w).Encode(map[string]string{"message": "Data saved successfully"})
99109
}
100110

111+
// UpdateStatus updates the status of a record based on RANDOM_ID
101112
func UpdateStatus(w http.ResponseWriter, r *http.Request) {
102113
var input StatusModel
103114

@@ -120,6 +131,7 @@ func UpdateStatus(w http.ResponseWriter, r *http.Request) {
120131
json.NewEncoder(w).Encode(map[string]string{"message": "Record updated successfully"})
121132
}
122133

134+
// GetDataJSON fetches all data from MongoDB
123135
func GetDataJSON(w http.ResponseWriter, r *http.Request) {
124136
var records []DataModel
125137
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -144,6 +156,270 @@ func GetDataJSON(w http.ResponseWriter, r *http.Request) {
144156
w.Header().Set("Content-Type", "application/json")
145157
json.NewEncoder(w).Encode(records)
146158
}
159+
func GetPaginatedData(w http.ResponseWriter, r *http.Request) {
160+
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
161+
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
162+
if page < 1 {
163+
page = 1
164+
}
165+
if limit < 1 {
166+
limit = 10
167+
}
168+
skip := (page - 1) * limit
169+
var records []DataModel
170+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
171+
defer cancel()
172+
173+
options := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit))
174+
cursor, err := collection.Find(ctx, bson.M{}, options)
175+
if err != nil {
176+
http.Error(w, err.Error(), http.StatusInternalServerError)
177+
return
178+
}
179+
defer cursor.Close(ctx)
180+
181+
for cursor.Next(ctx) {
182+
var record DataModel
183+
if err := cursor.Decode(&record); err != nil {
184+
http.Error(w, err.Error(), http.StatusInternalServerError)
185+
return
186+
}
187+
records = append(records, record)
188+
}
189+
190+
w.Header().Set("Content-Type", "application/json")
191+
json.NewEncoder(w).Encode(records)
192+
}
193+
194+
func GetSummary(w http.ResponseWriter, r *http.Request) {
195+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
196+
defer cancel()
197+
198+
totalCount, err := collection.CountDocuments(ctx, bson.M{})
199+
if err != nil {
200+
http.Error(w, err.Error(), http.StatusInternalServerError)
201+
return
202+
}
203+
204+
statusCount := make(map[string]int64)
205+
nsappCount := make(map[string]int64)
206+
207+
pipeline := []bson.M{
208+
{"$group": bson.M{"_id": "$status", "count": bson.M{"$sum": 1}}},
209+
}
210+
cursor, err := collection.Aggregate(ctx, pipeline)
211+
if err == nil {
212+
for cursor.Next(ctx) {
213+
var result struct {
214+
ID string `bson:"_id"`
215+
Count int64 `bson:"count"`
216+
}
217+
if err := cursor.Decode(&result); err == nil {
218+
statusCount[result.ID] = result.Count
219+
}
220+
}
221+
}
222+
223+
pipeline = []bson.M{
224+
{"$group": bson.M{"_id": "$nsapp", "count": bson.M{"$sum": 1}}},
225+
}
226+
cursor, err = collection.Aggregate(ctx, pipeline)
227+
if err == nil {
228+
for cursor.Next(ctx) {
229+
var result struct {
230+
ID string `bson:"_id"`
231+
Count int64 `bson:"count"`
232+
}
233+
if err := cursor.Decode(&result); err == nil {
234+
nsappCount[result.ID] = result.Count
235+
}
236+
}
237+
}
238+
239+
response := CountResponse{
240+
TotalEntries: totalCount,
241+
StatusCount: statusCount,
242+
NSAPPCount: nsappCount,
243+
}
244+
245+
w.Header().Set("Content-Type", "application/json")
246+
json.NewEncoder(w).Encode(response)
247+
}
248+
249+
func GetByNsapp(w http.ResponseWriter, r *http.Request) {
250+
nsapp := r.URL.Query().Get("nsapp")
251+
var records []DataModel
252+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
253+
defer cancel()
254+
255+
cursor, err := collection.Find(ctx, bson.M{"nsapp": nsapp})
256+
if err != nil {
257+
http.Error(w, err.Error(), http.StatusInternalServerError)
258+
return
259+
}
260+
defer cursor.Close(ctx)
261+
262+
for cursor.Next(ctx) {
263+
var record DataModel
264+
if err := cursor.Decode(&record); err != nil {
265+
http.Error(w, err.Error(), http.StatusInternalServerError)
266+
return
267+
}
268+
records = append(records, record)
269+
}
270+
271+
w.Header().Set("Content-Type", "application/json")
272+
json.NewEncoder(w).Encode(records)
273+
}
274+
275+
func GetByDateRange(w http.ResponseWriter, r *http.Request) {
276+
277+
startDate := r.URL.Query().Get("start_date")
278+
endDate := r.URL.Query().Get("end_date")
279+
280+
if startDate == "" || endDate == "" {
281+
http.Error(w, "Both start_date and end_date are required", http.StatusBadRequest)
282+
return
283+
}
284+
285+
start, err := time.Parse("2006-01-02T15:04:05.999999+00:00", startDate+"T00:00:00+00:00")
286+
if err != nil {
287+
http.Error(w, "Invalid start_date format", http.StatusBadRequest)
288+
return
289+
}
290+
291+
end, err := time.Parse("2006-01-02T15:04:05.999999+00:00", endDate+"T23:59:59+00:00")
292+
if err != nil {
293+
http.Error(w, "Invalid end_date format", http.StatusBadRequest)
294+
return
295+
}
296+
297+
var records []DataModel
298+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
299+
defer cancel()
300+
301+
cursor, err := collection.Find(ctx, bson.M{
302+
"created_at": bson.M{
303+
"$gte": start,
304+
"$lte": end,
305+
},
306+
})
307+
if err != nil {
308+
http.Error(w, err.Error(), http.StatusInternalServerError)
309+
return
310+
}
311+
defer cursor.Close(ctx)
312+
313+
for cursor.Next(ctx) {
314+
var record DataModel
315+
if err := cursor.Decode(&record); err != nil {
316+
http.Error(w, err.Error(), http.StatusInternalServerError)
317+
return
318+
}
319+
records = append(records, record)
320+
}
321+
322+
w.Header().Set("Content-Type", "application/json")
323+
json.NewEncoder(w).Encode(records)
324+
}
325+
func GetByStatus(w http.ResponseWriter, r *http.Request) {
326+
status := r.URL.Query().Get("status")
327+
var records []DataModel
328+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
329+
defer cancel()
330+
331+
cursor, err := collection.Find(ctx, bson.M{"status": status})
332+
if err != nil {
333+
http.Error(w, err.Error(), http.StatusInternalServerError)
334+
return
335+
}
336+
defer cursor.Close(ctx)
337+
338+
for cursor.Next(ctx) {
339+
var record DataModel
340+
if err := cursor.Decode(&record); err != nil {
341+
http.Error(w, err.Error(), http.StatusInternalServerError)
342+
return
343+
}
344+
records = append(records, record)
345+
}
346+
347+
w.Header().Set("Content-Type", "application/json")
348+
json.NewEncoder(w).Encode(records)
349+
}
350+
351+
func GetByOS(w http.ResponseWriter, r *http.Request) {
352+
osType := r.URL.Query().Get("os_type")
353+
osVersion := r.URL.Query().Get("os_version")
354+
var records []DataModel
355+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
356+
defer cancel()
357+
358+
cursor, err := collection.Find(ctx, bson.M{"os_type": osType, "os_version": osVersion})
359+
if err != nil {
360+
http.Error(w, err.Error(), http.StatusInternalServerError)
361+
return
362+
}
363+
defer cursor.Close(ctx)
364+
365+
for cursor.Next(ctx) {
366+
var record DataModel
367+
if err := cursor.Decode(&record); err != nil {
368+
http.Error(w, err.Error(), http.StatusInternalServerError)
369+
return
370+
}
371+
records = append(records, record)
372+
}
373+
374+
w.Header().Set("Content-Type", "application/json")
375+
json.NewEncoder(w).Encode(records)
376+
}
377+
378+
func GetErrors(w http.ResponseWriter, r *http.Request) {
379+
errorCount := make(map[string]int)
380+
381+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
382+
defer cancel()
383+
384+
cursor, err := collection.Find(ctx, bson.M{"error": bson.M{"$ne": ""}})
385+
if err != nil {
386+
http.Error(w, err.Error(), http.StatusInternalServerError)
387+
return
388+
}
389+
defer cursor.Close(ctx)
390+
391+
for cursor.Next(ctx) {
392+
var record DataModel
393+
if err := cursor.Decode(&record); err != nil {
394+
http.Error(w, err.Error(), http.StatusInternalServerError)
395+
return
396+
}
397+
398+
if record.ERROR != "" {
399+
errorCount[record.ERROR]++
400+
}
401+
}
402+
403+
type ErrorCountResponse struct {
404+
Error string `json:"error"`
405+
Count int `json:"count"`
406+
}
407+
408+
var errorCounts []ErrorCountResponse
409+
for err, count := range errorCount {
410+
errorCounts = append(errorCounts, ErrorCountResponse{
411+
Error: err,
412+
Count: count,
413+
})
414+
}
415+
416+
w.Header().Set("Content-Type", "application/json")
417+
json.NewEncoder(w).Encode(struct {
418+
ErrorCounts []ErrorCountResponse `json:"error_counts"`
419+
}{
420+
ErrorCounts: errorCounts,
421+
})
422+
}
147423

148424
func main() {
149425
ConnectDatabase()
@@ -152,6 +428,13 @@ func main() {
152428
router.HandleFunc("/upload", UploadJSON).Methods("POST")
153429
router.HandleFunc("/upload/updatestatus", UpdateStatus).Methods("POST")
154430
router.HandleFunc("/data/json", GetDataJSON).Methods("GET")
431+
router.HandleFunc("/data/paginated", GetPaginatedData).Methods("GET")
432+
router.HandleFunc("/data/summary", GetSummary).Methods("GET")
433+
router.HandleFunc("/data/nsapp", GetByNsapp).Methods("GET")
434+
router.HandleFunc("/data/date", GetByDateRange).Methods("GET")
435+
router.HandleFunc("/data/status", GetByStatus).Methods("GET")
436+
router.HandleFunc("/data/os", GetByOS).Methods("GET")
437+
router.HandleFunc("/data/errors", GetErrors).Methods("GET")
155438

156439
c := cors.New(cors.Options{
157440
AllowedOrigins: []string{"*"},

0 commit comments

Comments
 (0)