Muhammet Ali Topcu Individual Contribution Report 2 - bounswe/bounswe2023group1 GitHub Wiki

Muhammet Ali Topcu

Important Issues

Links: #153
Explanation: Firstly, we decided to work with Kotlin & Gradle. Ilgaz dealed with it at first. But later, since we were more familiar with Java & Maven, we switched to Java 17 and Maven. I created a Spring boot application from Spring initializr, added the base dependencies for the project. Also, I created the main React application with npx-create-react-app. I created the main page with directions so that every team member can add their navigation link to the navbar and direct the user to their page. Every team member was required to create their own page and add UI implementation part of their code.

Links: #169 #190 #203
I researched the Swagger API Development support tools with Ilgaz Er. At first, we just used npm and I implemented Swagger UI accordingly. Later, when we migrate to nginx with the help of Ilgaz, Swagger UI endpoint didn't work. Then, Ilgaz fixed the problem and it is working now.

Links: #158 #180 #181 #184 #185
Explanation: I containerized the backend, frontend and database parts of the project. Initially, I created docker-compose.yml and one Dockerfile for backend and another one for frontend. After migrating to nginx, Ilgaz split the files into two as docker-compose.yml and docker-compose_dev.yml and Dockerfile and Dockerfile_dev for production and dev environments. We had some problem to connect frontend to backend and backend to database in Docker container. So, at one branch, I worked to implement it without using nginx in the project and at another branch Ilgaz worked to implement it with using nginx. I successfully completed the connections between them. Later, Ilgaz also was successful at completing the connections. So, we migrated back to nginx branch and continued to working on the project.

Links: #162 #164 #173 #175 #176 #178 #189 #201 #206
Explanation: Implementation of Google Directions API. Created a class in controller package called DirectionsController to meet the user requests. Then, forwarded the requests to DirectionsService class, which is located at service package, so that it could be processed at service layer. Also, created one entity called BookmarkedDestination and one repository for this entity called BookmarkedDestinationRepository. Used Spring Data JPA to create Data Access Objects(DAOs) and used Hibernate as Object Relational Mapping(ORM) with database PostgreSQL. Implemented frontend part with ReactJs. At last, I wrote unit tests for the methods located at DirectionsService.

Utilized Third Party URI

Google Directions API, https://developers.google.com/maps/documentation/directions/overview

The Directions API is a service that accepts an HTTP request and returns JSON or XML-formatted directions between locations. With the Directions API, you can get directions for several modes of transportation, such as transit, driving, walking, or bicycling.

Users are able to send GET request to /getDirection endpoint, which uses Google Directions API at backend. Also, users are able to send POST request to /saveDestination endpoint so that they can save whatever destination they want to save. Finally, users are able to send GET request to /getBookmarkedDestinations to fetch all bookmarked destinations from database.

At the beginning of the semester, I researched this API and in this part of the project, I get a chance to use it.

API Endpoints

GET /getDirection with request parameters from:string, to:string. This API endpoint allows user to get directions between given two locations using Google Directions API.
POST /saveDestination with request parameters destination:string. This API endpoint allows user to save the given destination to the database for future use.
GET /getBookmarkedDestinations. This API endpoint allows user to fetch all saved destinations.

Unit Tests

Used to test whether GET /getBookmarkedDestinations method works as intended when there exists some saved destinations. getbookmarkeddestinationsvalid

Used to test whether GET /getBookmarkedDestinations method works as intended when there exists no saved destinations. getbookmarkeddestinationsinvalid

Used to test whether POST /saveDestination method saves when there exists no destination saved with the same name. savedestinationvalid

Used to test whether POST /saveDestination method doesn't saves when there exists a destination saved with the same name. savedestinationinvalid

Sample Calls

Sample Request: 1

Request: GET http://localhost:4000/api/getDirection?from=bogazici&to=etiler

Response:
Header:
header1

Body: { "geocoded_waypoints" : [ { "geocoder_status" : "OK", "partial_match" : true, "place_id" : "ChIJc637R__JyhQRDs1GXJiVZL0", "types" : [ "establishment", "point_of_interest", "university" ] }, { "geocoder_status" : "OK", "place_id" : "ChIJU4-x7AW2yhQRzhv5ydjvaXs", "types" : [ "administrative_area_level_4", "political" ] } ], "routes" : [ { "bounds" : { "northeast" : { "lat" : 41.0870537, "lng" : 29.0504899 }, "southwest" : { "lat" : 41.0785154, "lng" : 29.037294 } }, "copyrights" : "Map data \u00a92023", "legs" : [ { "distance" : { "text" : "1.8 km", "value" : 1820 }, "duration" : { "text" : "6 mins", "value" : 363 }, "end_address" : "Etiler, 34337 Be\u015fikta\u015f/\u0130stanbul, T\u00fcrkiye", "end_location" : { "lat" : 41.0870537, "lng" : 29.037294 }, "start_address" : "Bebek, 34342 Be\u015fikta\u015f/\u0130stanbul, T\u00fcrkiye", "start_location" : { "lat" : 41.080058, "lng" : 29.0504417 }, "steps" : [ { "distance" : { "text" : "11 m", "value" : 11 }, "duration" : { "text" : "1 min", "value" : 1 }, "end_location" : { "lat" : 41.0799631, "lng" : 29.0504899 }, "html_instructions" : "Head \u003cb\u003esouth\u003c/b\u003e on \u003cb\u003eB\u00dc G\u00fcney Kamp\u00fcs\u00fc\u003c/b\u003e toward \u003cb\u003eCevdet Pa\u015fa Cd.\u003c/b\u003e", "polyline" : { "points" : "kmvyFg|hpDJEFC" }, "start_location" : { "lat" : 41.080058, "lng" : 29.0504417 }, "travel_mode" : "DRIVING" }, { "distance" : { "text" : "0.5 km", "value" : 492 }, "duration" : { "text" : "1 min", "value" : 88 }, "end_location" : { "lat" : 41.0785154, "lng" : 29.0450616 }, "html_instructions" : "Turn \u003cb\u003eright\u003c/b\u003e onto \u003cb\u003eCevdet Pa\u015fa Cd.\u003c/b\u003e", "maneuver" : "turn-right", "polyline" : { "points" : "wlvyFq|hpDPfAh@|Ch@bDHn@F`AL`CBn@@^Dj@@P@LBLDLDJDL`@p@b@p@@BJRHRFNDN@JBP@^" }, "start_location" : { "lat" : 41.0799631, "lng" : 29.0504899 }, "travel_mode" : "DRIVING" }, { "distance" : { "text" : "0.8 km", "value" : 825 }, "duration" : { "text" : "3 mins", "value" : 185 }, "end_location" : { "lat" : 41.0847836, "lng" : 29.0410311 }, "html_instructions" : "Turn \u003cb\u003eright\u003c/b\u003e onto \u003cb\u003eK\u00fc\u00e7\u00fck Bebek Cd.\u003c/b\u003e", "maneuver" : "turn-right", "polyline" : { "points" : "wcvyFszgpDQEO?WAa@BUB[FID_@HiAHa@HWFIDEDEDIH_AT]L[LWTk@l@UTEPIPYl@U\\CDMNGBE@A?E?I@E@EBA@A@CBEDABAF?DAD?@?D?J@LBLWPKHCBC@E@C@C?E?C?E?K?K?E?[?W@O@C?I@WHEB[JMHOJKFGFY\\i@d@QNGBMHQLQNKHm@l@e@l@QL" }, "start_location" : { "lat" : 41.0785154, "lng" : 29.0450616 }, "travel_mode" : "DRIVING" }, { "distance" : { "text" : "0.3 km", "value" : 293 }, "duration" : { "text" : "1 min", "value" : 47 }, "end_location" : { "lat" : 41.0857702, "lng" : 29.0379119 }, "html_instructions" : "At the roundabout, take the \u003cb\u003e2nd\u003c/b\u003e exit onto \u003cb\u003eCengiz Topel Cd.\u003c/b\u003e", "maneuver" : "roundabout-right", "polyline" : { "points" : "{jwyFmagpDA?A?A?A?A?A?A@A@A?A@?@A@A@?@?@?@?@?@?@?@?@?@?@?@I`@AJADCN?F?Bm@vEGp@CVERCPETELELITO^Wf@Sd@" }, "start_location" : { "lat" : 41.0847836, "lng" : 29.0410311 }, "travel_mode" : "DRIVING" }, { "distance" : { "text" : "53 m", "value" : 53 }, "duration" : { "text" : "1 min", "value" : 13 }, "end_location" : { "lat" : 41.08614800000001, "lng" : 29.038288 }, "html_instructions" : "Turn \u003cb\u003eright\u003c/b\u003e onto \u003cb\u003eKo\u00e7yi\u011fitler Sk.\u003c/b\u003e", "maneuver" : "turn-right", "polyline" : { "points" : "aqwyF}mfpDYYOMa@c@" }, "start_location" : { "lat" : 41.0857702, "lng" : 29.0379119 }, "travel_mode" : "DRIVING" }, { "distance" : { "text" : "37 m", "value" : 37 }, "duration" : { "text" : "1 min", "value" : 8 }, "end_location" : { "lat" : 41.0864817, "lng" : 29.0383234 }, "html_instructions" : "Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eF\u00fczeciler Sk.\u003c/b\u003e", "maneuver" : "turn-left", "polyline" : { "points" : "mswyFipfpDO?OAWAIA" }, "start_location" : { "lat" : 41.08614800000001, "lng" : 29.038288 }, "travel_mode" : "DRIVING" }, { "distance" : { "text" : "0.1 km", "value" : 109 }, "duration" : { "text" : "1 min", "value" : 21 }, "end_location" : { "lat" : 41.0870537, "lng" : 29.037294 }, "html_instructions" : "Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eMuharipler Sk.\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003eDestination will be on the left\u003c/div\u003e", "maneuver" : "turn-left", "polyline" : { "points" : "ouwyFopfpDIRk@jBKVIPKLOLIF" }, "start_location" : { "lat" : 41.0864817, "lng" : 29.0383234 }, "travel_mode" : "DRIVING" } ], "traffic_speed_entry" : [], "via_waypoint" : [] } ], "overview_polyline" : { "points" : "kmvyFg|hpDRIz@dFr@rETbELlCDZJXlAtBTf@L^D\\@^QEg@Aw@Fe@L_@HiAHy@POJON}Ab@[LWTaAbAOb@o@jAQTMDWBMJIVAXDZc@ZQHmA?u@D]Li@Tc@ZcAbAYR}@p@m@l@e@l@SLE?C?KL?J?BKp@E`@_AtHUbAeAbCi@g@a@c@O?g@CIAIRw@bCU^YT" }, "summary" : "Cevdet Pa\u015fa Cd. and K\u00fc\u00e7\u00fck Bebek Cd.", "warnings" : [], "waypoint_order" : [] } ], "status" : "OK" }

Sample Request: 2

Request: POST http://localhost:4000/api/saveDestination?destination=bogazici

Response:
Header:
header2

Body: CREATED

Sample Request: 3

Request: GET http://localhost:4000/api/saveDestination?destination=bogazici

Response:
Header:
header3

Body: [{"id":1,"address":"bogazici"}]

Significant Work

Implemented first versions of docker-compose.yml and Dockerfiles. Later, updated by Ilgaz Er. Dealed with contarizing the whole application and ensuring that they are all at the same network and connected to each other so that frontend can interact with backend and backend can interact with database. Contributed to choose Spring Boot as backend framework, ReactJs as frontend library and PostgreSQL as database. Initialized Spring Boot app with Spring initializr, ReactJs with npx create-react-app and connected backend to frontend with configs located at application.properties based in backend folder src/main/resources.

Challenges

Most challenging part for me was connections between docker containers. I get error as "Could not proxy request from localhost:3000 to http://localhost:8080/". After inspecting the page https://docs.docker.com/compose/networking/, I realized that we should provide a network for the containers and also use containers' name to refer to each other. For example, instead of localhost:8080, we must use backend:8080 (if the name of the container is backend). Also, the connection between backend and database was the other challenge for me. Creating network solved the problem.

⚠️ **GitHub.com Fallback** ⚠️