{"id":14977521,"url":"https://github.com/mariazevedo88/travels-java-api","last_synced_at":"2025-04-06T04:11:25.037Z","repository":{"id":48031519,"uuid":"206915546","full_name":"mariazevedo88/travels-java-api","owner":"mariazevedo88","description":"An API for travel management. It is built with Java, Spring Boot, and Spring Framework. A toy-project to serve as a theoretical basis for the Medium series of articles I wrote about Java+Spring.","archived":false,"fork":false,"pushed_at":"2024-05-11T12:06:41.000Z","size":317,"stargazers_count":254,"open_issues_count":2,"forks_count":124,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-30T02:09:44.807Z","etag":null,"topics":["api","api-restful","api-service","http","http-rest-api","java","java-11","java-api","java-api-for-restful-web-services","java-rest-api","java-restful-api","java11","medium-article","rest","rest-api","restful-api","spring-boot","spring-framework","swagger-api","swagger-documentation"],"latest_commit_sha":null,"homepage":"https://medium.com/@mari_azevedo/construindo-uma-api-restful-com-java-e-spring-framework-46b74371d107","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mariazevedo88.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-07T04:29:49.000Z","updated_at":"2025-03-25T03:35:49.000Z","dependencies_parsed_at":"2024-09-18T22:04:56.810Z","dependency_job_id":"8a2a64b1-f09c-40fc-a92d-ad69c6b394ea","html_url":"https://github.com/mariazevedo88/travels-java-api","commit_stats":{"total_commits":89,"total_committers":2,"mean_commits":44.5,"dds":0.1235955056179775,"last_synced_commit":"3a7fd4cc36938666f09ee5945a28345763105075"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariazevedo88%2Ftravels-java-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariazevedo88%2Ftravels-java-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariazevedo88%2Ftravels-java-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariazevedo88%2Ftravels-java-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mariazevedo88","download_url":"https://codeload.github.com/mariazevedo88/travels-java-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247430870,"owners_count":20937874,"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","api-restful","api-service","http","http-rest-api","java","java-11","java-api","java-api-for-restful-web-services","java-rest-api","java-restful-api","java11","medium-article","rest","rest-api","restful-api","spring-boot","spring-framework","swagger-api","swagger-documentation"],"created_at":"2024-09-24T13:55:49.032Z","updated_at":"2025-04-06T04:11:24.932Z","avatar_url":"https://github.com/mariazevedo88.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# travels-java-api\n\n[![Build Status](https://travis-ci.org/mariazevedo88/travels-java-api.svg?branch=master)](https://travis-ci.org/mariazevedo88/travels-java-api) ![GitHub forks](https://img.shields.io/github/forks/mariazevedo88/travels-java-api?style=social) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/mariazevedo88/travels-java-api) ![GitHub language count](https://img.shields.io/github/languages/count/mariazevedo88/travels-java-api) ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/mariazevedo88/travels-java-api) ![GitHub repo size](https://img.shields.io/github/repo-size/mariazevedo88/travels-java-api) ![GitHub last commit](https://img.shields.io/github/last-commit/mariazevedo88/travels-java-api) ![GitHub](https://img.shields.io/github/license/mariazevedo88/travels-java-api)\n\n## About the API\n\nAn API for travel management. It is built with Java, Spring Boot, and Spring Framework. A toy-project to serve as a theoretical basis for the Medium series of articles I wrote about Java+Spring. The API main URL `/api-travels/v1`.\n\n## Features\n\nThis API provides HTTP endpoint's and tools for the following:\n\n* Create a trip: `POST/api-travels/v1/travels`\n* Update a trip: `PUT/api-travels/v1/travels`\n* Delete a trip (by id): `DELETE/api-travels/v1/travels/1`\n* Get report of travels in a period of time (sorted and paginated): `GET/api-travels/v1/travels?startDate=2020-01-01\u0026endDate=2020-09-20\u0026page=2\u0026size=5\u0026sort=DESC`\n* Find a unique trip by id: `GET/api-travels/v1/travels/1`\n* Find a unique trip by id, but filtering JSON fields: `GET/api-travels/v1/travels/1?fields=id,orderNumber,startDate,amount`\n* Find a trip by the order number (unique id on the system): `GET/api-travels/v1/travels/byOrderNumber/{orderNumber}`\n* Get Statistics about the travels of the API: `GET/api-travels/v1/statistics`\n\n### Details\n\n`POST/api-travels/v1/travels`\n\nThis end-point is called to create a new trip.\n\n**Body:**\n\n```json\n{\n  \"orderNumber\": \"123456\",\n  \"amount\": \"22.88\",\n  \"startDate\": \"2020-04-05T09:59:51.312Z\",\n  \"endDate\": \"2020-04-15T16:25:00.500Z\",\n  \"type\": \"RETURN\"\n}\n```\n\n**Where:**\n\n`id` - travel id. It is automatically generated.\n\n`orderNumber` - identification number of a trip on the system.\n\n`amount` – travel amount; a string of arbitrary length that is parsable as a BigDecimal;\n\n`startDate` – travel start date time in the ISO 8601 format YYYY-MM-DDThh:mm:ss.sssZ in the Local time zone.\n\n`endDate` – end date of the trip in the ISO 8601 format YYYY-MM-DDThh:mm:ss.sssZ in the Local time zone.\n\n`type` - travel type: ONE-WAY, RETURN or MULTI-CITY.\n\n`links` - self-linking URL for the travel. It is automatically generated.\n\nReturns an empty body with one of the following:\n\n* 201 - Created: Everything worked as expected.\n* 400 - Bad Request: the request was unacceptable, often due to missing a required parameter or invalid JSON.\n* 404 - Not Found: The requested resource doesn't exist.\n* 409 - Conflict: The request conflicts with another request (perhaps due to using the same idempotent key).\n* 422 – Unprocessable Entity: if any of the fields are not parsable or the start date is greater than the end date.\n* 429 - Too Many Requests: Too many requests hit the API too quickly. We recommend an exponential back-off of your requests.\n* 500, 502, 503, 504 - Server Errors: something went wrong on API end (These are rare).\n\n`PUT/api-travels/v1/travels/{id}`\n\nThis end-point is called to update a trip.\n\n**Body:**\n\n```json\n{\n   \"id\": 1,\n   \"orderNumber\": \"123456\",\n   \"amount\": \"30.06\",\n   \"startDate\": \"2020-04-05T09:59:51.312Z\",\n   \"endDate\": \"2020-04-15T16:25:00.500Z\",\n   \"type\": \"RETURN\"\n}\n```\n\nMust be submitted the object that will be modified. Must return a trip specified by ID and all fields recorded above, including links and the one that was updated.\n\n```json\n{\n   \"data\": {   \n   \t\t\"id\": 1,\n   \t\t\"orderCode\": \"123456\",\n   \t\t\"amount\": \"30.06\",\n   \t\t\"startDate\": \"2020-04-05T09:59:51.312Z\",\n  \t\t\"endDate\": \"2020-04-15T16:25:00.500Z\",\n  \t\t\"type\": \"RETURN\",\n   \t\t\"links\": [\n\t\t\t{\n\t\t\t\"rel\": \"self\",\n\t\t\t\t\"href\": \"http://localhost:8080/api-travels/v1/travels/1\"\n\t\t\t}\n   \t\t]\n\t}\n}\n```\n\n`GET/api-travels/v1/travels?startDate=2020-01-01\u0026endDate=2020-01-18\u0026page=2\u0026size=5\u0026sort=DESC`\n\nThe end-point returns travels were created within the period specified in the request. E.g., in the above query, we are looking for all travels carried out between 01-18 January 2020. Also, the result should return in descending order and only page 2\nwith five trips.\n\n`DELETE/api-travels/v1/travels/{id}`\n\nThis end-point causes a specific id to be deleted, accepting an empty request body and returning a 204 status code.\n\n**Where:**\n\n`id` - travel id to be deleted.\n\n`GET/api-travels/v1/statistics`\n\nThis end-point returns the statistics based on the travels created.\n\n**Returns:**\n\n```json\n{\n\t\"data\": { \n  \t\t\"sum\": \"150.06\",\n  \t\t\"avg\": \"75.3\",\n  \t\t\"max\": \"120.0\",\n  \t\t\"min\": \"30.06\",\n  \t\t\"count\": 2,\n  \t\t\"links\": [\n\t\t\t{\n\t\t\t\"rel\": \"self\",\n\t\t\t\t\"href\": \"http://localhost:8080/api-travels/v1/statistics/1\"\n\t\t\t}\n   \t\t]\n   \t}\n}\n```\n \n**Where:**\n\n`sum` – a BigDecimal specifying the total sum of the amount of all travels.\n\n`avg` – a BigDecimal specifying the average of the amount of all travels.\n\n`max` – a BigDecimal specifying single highest travel value.\n\n`min` – a BigDecimal specifying single lowest travel value.\n\n`count` – a long specifying the total number of travels.\n\n`links` - self-linking URL for the statistic. It is automatically generated.\n\nAll `BigDecimal` values always contain exactly two decimal places, e.g: `15.385` is returned as `15.39`.\n\n### Technologies used\n\nThis project was developed with:\n\n* **Java 11 (Java Development Kit - JDK: 11.0.9)**\n* **Spring Boot 2.3.7**\n* **Spring Admin Client 2.3.1**\n* **Maven**\n* **JUnit 5**\n* **Surfire**\n* **PostgreSQL 13**\n* **Flyway 6.4.4**\n* **Swagger 3.0.0**\n* **Model Mapper 2.3.9**\n* **Heroku**\n* **EhCache**\n* **Bucket4j 4.10.0**\n* **Partialize 20.05**\n\n### Compile and Package\n\nThe API also was developed to run with an `jar`. In order to generate this `jar`, you should run:\n\n```bash\nmvn package\n```\n\nIt will clean, compile and generate a `jar` at target directory, e.g. `travels-java-api-5.0.1-SNAPSHOT.jar`\n\n### Execution\n\nYou need to have **PostgreSQL 9.6.17 or above** installed on your machine to run the API on `dev` profile. After installed, on the `pgAdmin` create a database named `travels`. If you don't have `pgAdmin` installed you can run on the `psql` console the follow command:\n\n```sql\nCREATE database travels;\n```\n\nAfter creating the API database, you need to add your **Postgres** root `username` and `password` in the `application.properties` file on `src/main/resource`. The lines that must be modified are as follows:\n\n```properties\nspring.datasource.username=\nspring.datasource.password=\n```\n\nWhen the application is running **Flyway** will create the necessary tables for the creation of the words and the execution of the compare between the end-points. In the test profile, the application uses **H2** database (data in memory).\n\n### Test\n\n* For unit test phase, you can run:\n\n```bash\nmvn test\n```\n\n* To run all tests (including Integration Tests):\n\n```bash\nmvn integration-test\n```\n\n### Run\n\nIn order to run the API, run the jar simply as following:\n\n```bash\njava -jar travels-java-api-5.0.1-SNAPSHOT.jar --spring.profiles.active=dev\n```\n    \nor\n\n```bash\nmvn spring-boot:run -Dspring.profiles.active=dev\n```\n\nBy default, the API will be available at [http://localhost:8080/api-travels/v1](http://localhost:8080/api-travels/v1)\n\n### Documentation\n\n* Swagger (development environment): [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html)\n\n#### Medium Articles\n\n* [Construindo uma API RESTful com Java e Spring Framework— Parte 1 (PT-BR)](https://medium.com/@mari_azevedo/construindo-uma-api-restful-com-java-e-spring-framework-46b74371d107)\n* [Construindo uma API RESTful com Java e Spring Framework— Parte 2 (PT-BR)](https://medium.com/@mari_azevedo/construindo-uma-api-restful-com-java-e-spring-framework-parte-2-7a6c3e2ad453)\n* [Construindo uma API RESTful com Java e Spring Framework— Parte 3 (PT-BR)](https://medium.com/@mari_azevedo/construindo-uma-api-restful-com-java-e-spring-framework-parte-3-ab34fcc00dee)\n* [Construindo uma API RESTful com Java e Spring Framework— Parte 4 (PT-BR)](https://medium.com/@mari_azevedo/construindo-uma-api-restful-com-java-e-spring-framework-parte-4-6287f68ffc3c)\n* [Building a RESTful API with Java and Spring Framework — Part 1 (EN)](https://mari-azevedo.medium.com/building-a-restful-api-with-java-and-spring-framework-part-1-6c364a885831)\n\n### License\n\nThis API is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmariazevedo88%2Ftravels-java-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmariazevedo88%2Ftravels-java-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmariazevedo88%2Ftravels-java-api/lists"}