{"id":24185120,"url":"https://github.com/alexandre-touret/rest-apis-versioning-workshop","last_synced_at":"2025-09-21T08:31:41.264Z","repository":{"id":63361843,"uuid":"559565060","full_name":"alexandre-touret/rest-apis-versioning-workshop","owner":"alexandre-touret","description":"Rest APIs Versioning","archived":false,"fork":false,"pushed_at":"2024-01-31T14:15:40.000Z","size":639,"stargazers_count":5,"open_issues_count":0,"forks_count":19,"subscribers_count":1,"default_branch":"2H_WORKSHOP","last_synced_at":"2024-04-15T06:35:19.286Z","etag":null,"topics":["docker","java","microservices","rest-api","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexandre-touret.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}},"created_at":"2022-10-30T14:11:26.000Z","updated_at":"2023-10-26T19:45:54.000Z","dependencies_parsed_at":"2023-12-15T15:29:25.317Z","dependency_job_id":"d836a163-bcd7-40a9-8c2a-dba7048f0a6a","html_url":"https://github.com/alexandre-touret/rest-apis-versioning-workshop","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-touret%2Frest-apis-versioning-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-touret%2Frest-apis-versioning-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-touret%2Frest-apis-versioning-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-touret%2Frest-apis-versioning-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexandre-touret","download_url":"https://codeload.github.com/alexandre-touret/rest-apis-versioning-workshop/tar.gz/refs/heads/2H_WORKSHOP","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233731144,"owners_count":18721286,"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":["docker","java","microservices","rest-api","spring-boot"],"created_at":"2025-01-13T11:18:40.510Z","updated_at":"2025-09-21T08:31:35.907Z","avatar_url":"https://github.com/alexandre-touret.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n# REST APIs Versioning: Hands-on !\r\n\r\nThis workshop aims to \r\n- Introduce REST API Versioning \r\n- Highlight API breaking and non breaking changes\r\n- Dive into all the impacts: configuration, code, security,...  \r\n\r\n## :dart: Big picture\r\n\r\nDuring this workshop we will strive with API versioning on a (small) microservice application.\r\nHere is a short description of it.\r\n\r\nThis platform aims to store and get books of a bookstore.\r\n\r\n### System View\r\n\r\n```mermaid\r\nC4Context\r\n      title System Context diagram for Bookstore System\r\n      Person(customerA, \"Bookstore Customer\", \"A customer of the bookstore\") \r\n      Person(adminA, \"Bookstore Administrator\", \"An administrator of \u003cbr/\u003e the bookstore\") \r\n      Enterprise_Boundary(b0, \"Bookstore Boundary\") {\r\n        System(bookstoreSystem, \"Bookstore System\", \"Allows Book \u003cbr/\u003e creation, search,...\")  \r\n        System(iamSystem, \"Bookstore IAM\", \"Allows Identification \u003cbr/\u003e \u0026 authorization...\")  \r\n      }\r\n      Rel(customerA, bookstoreSystem, \"Uses\")\r\n      Rel(adminA, bookstoreSystem, \"Uses \u0026 manage users\")\r\n      Rel(customerA, iamSystem, \"identifies \u0026 authorizes\")\r\n      Rel(adminA, iamSystem, \"identifies \u0026 authorizes\")\r\n```\r\n\r\n#### Explanations\r\n\r\nHere we have two main kind of users:\r\n* Customer : He can browse and create books\r\n* Administrator: He can create books and activate/deactivate the maintenance mode\r\n\r\nWithin our platform, we have two main systems:\r\n\r\n* Bookstore system which operate all the book related operations\r\n* Bookstore IAM which is responsible for identifying and authorizing users\r\n\r\n### Container view\r\n\r\n```mermaid\r\nC4Container\r\n      title Container Context diagram for Bookstore System\r\n\r\n\r\n      Person(customerA, \"Bookstore Customer\", \"A customer of the bookstore\") \r\n      Person(adminA, \"Bookstore Administrator\", \"An administrator \u003cbr/\u003e of the bookstore\") \r\n\r\n      Enterprise_Boundary(b0, \"Bookstore Boundary\") {\r\n        Container_Boundary(b2,\"Bookstore IAM\"){\r\n          Container(iam,\"IAM\",\"Provides a JWT token with roles in claims\")\r\n\r\n               }\r\n        Container_Boundary(b1,\"Bookstore System\"){\r\n            Container(bookstoreApi,\"Bookstore API\",\"Spring Boot, Cloud\",\"Exposes the Bookstore APIs\")\r\n            Container(gateway,\"API Gateway\",\"Spring Cloud Gateway\",\"Exposes the APIs\")\r\n            ContainerDb(database, \"Database\", \"PostgreSQL Database\", \"Stores bookstore\")\r\n            Container(isbnApi,\"ISBN\",\"Spring Boot, Cloud\",\"Exposes the ISBN APIs\")\r\n            Container(configuration,\"Configuration Server\",\"Spring Cloud Config\",\"Exposes the configuration\")\r\n            Container(zipkin,\"Zipkin\",\"Zipkin\",\"Gathers and \u003cbr/\u003e provides distributed tracing\")\r\n        }\r\n      }\r\n\r\n      Rel(customerA,gateway, \"Uses\")\r\n      Rel(adminA, gateway, \"Uses \u0026 manage users\")\r\n      Rel(customerA, iam, \"identifies \u0026 authorizes\")\r\n      Rel(adminA, iam, \"identifies \u0026 authorizes\")\r\n      Rel(gateway, iam, \"verify token\")\r\n      Rel(gateway, bookstoreApi, \"exposes\")\r\n      Rel(gateway, isbnApi, \"exposes\")\r\n      Rel(bookstoreApi, isbnApi, \"uses\")\r\n      Rel(bookstoreApi, database, \"stores data\")\r\n      UpdateLayoutConfig($c4ShapeInRow=\"3\", $c4BoundaryInRow=\"1\")\r\n```\r\n\r\n#### Explanations\r\n\r\nThis diagram digs into the systems exposed above in the system view.\r\n\r\nThe Bookstore system is composed of:\r\n* The API Gateway which exposes our APIs\r\n* The Bookstore API which exposes all the related book APIs and stores data to a PostgreSQL database\r\n* The ISBN API which provides random ISBN numbers\r\n* A Configuration server which centralizes all the configuration files\r\n\r\nThe Bookstore IAM is composed of:\r\n* A mock server which provides JWT token with appropriate roles and information.\r\n\r\n### :straight_ruler: Stack\r\nHere is a summary of the stack used in this workshop for this architecture:\r\n\r\n| Container | Tools                                                        | Comments |\r\n|---|--------------------------------------------------------------|---|\r\n| API Gateway | Spring Cloud Gateway 2023.0.0                                |  |\r\n| Bookstore API | JAVA 21,Spring Boot 3.2.X                                    |  |\r\n| ISBN API | JAVA 21,Spring Boot 3.2.X                                    |  |\r\n| Configuration Server | Spring Cloud Config 2023.0.0                                 |  |\r\n| Database | PostgreSQL                                                   |  |\r\n| Authorization Server | JAVA 21,Spring Boot 3.2.X, Spring Authorization Server 1.1.0 |  |\r\n\r\n\r\n### Customers\r\n\r\n## Our API Roadmap\r\n\r\n```mermaid\r\n%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'rotateCommitLabel': true}} }%%\r\ngitGraph:\r\n    commit id:\"Init\"\r\n    commit id: \"new features\" tag:\"Adding excerpt attribute \u0026 operation\"\r\n    branch V1\r\n    checkout V1\r\n    commit id:\"add URI PATH versions\"\r\n    commit id: \"add HTTP Header versions\"\r\n    commit id: \"add accept HTTP Header versions\"\r\n    checkout main\r\n    branch V2\r\n    commit id: \"revamping\"\r\n    commit id: \"Add author list feature\"\r\n    checkout V1\r\n    commit id: \"Add fallback behaviour in V1\"\r\n    checkout V2\r\n    commit id: \"Authorization management\"\r\n    merge V1\r\n    commit id: \"Deprecating V1\"\r\n```\r\n\r\n## :traffic_light: Prerequisites\r\n\r\n### :mortar_board: Skills\r\n\r\n| Skill                                                                                                                                                                                                                                                                                   | Level | \r\n|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|\r\n| [REST API](https://google.aip.dev/general)                                                                                                                                                                                                                                              | proficient |\r\n| [Java](https://www.oracle.com/java/)                                                                                                                                                                                                                                                    | novice |   \r\n| [Gradle](https://gradle.org/)                                                                                                                                                                                                                                                           | novice |\r\n| [Spring Framework](https://spring.io/projects/spring-framework), [Boot](https://spring.io/projects/spring-boot), [Cloud Config](https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_quick_start), [Cloud Gateway](https://spring.io/projects/spring-cloud-gateway) [Spring Authorization Server](https://docs.spring.io/spring-authorization-server/docs/current/reference/html/index.html)| novice |\r\n| [OpenID Connect](https://openid.net/connect)                                                                                                                                                                                                                                            | novice |]\r\n| [Docker](https://docs.docker.com/)                                                                                                                                                                                                                                                      | novice |\r\n\r\n### :wrench: Tools\r\n#### If you want to execute this workshop locally\r\nYou **MUST** have set up these tools first:\r\n* [Java 21+](https://adoptium.net/temurin/releases/?version=21)\r\n* [Gradle 8.5+](https://gradle.org/)\r\n* [Docker](https://docs.docker.com/) \u0026 [Docker compose](https://docs.docker.com/compose/)\r\n* Any IDE ([IntelliJ IDEA](https://www.jetbrains.com/idea), [VSCode](https://code.visualstudio.com/), [Netbeans](https://netbeans.apache.org/),...) you want\r\n* [cURL](https://curl.se/), [jq](https://stedolan.github.io/jq/), [HTTPie](https://httpie.io/) or any tool to call your REST APIs\r\n\r\nHere are commands to validate your environment:\r\n\r\n**Java**\r\n\r\n```jshelllanguage\r\njava -version\r\nopenjdk version \"21.0.1\" 2023-10-17 LTS\r\nOpenJDK Runtime Environment Temurin-21.0.1+12 (build 21.0.1+12-LTS)\r\nOpenJDK 64-Bit Server VM Temurin-21.0.1+12 (build 21.0.1+12-LTS, mixed mode, sharing)\r\n```\r\n\r\n**Gradle**\r\n\r\nIf you use the wrapper, you won't have troubles. Otherwise...:\r\n\r\n```jshelllanguage\r\ngradle -version\r\n\r\n------------------------------------------------------------\r\nGradle 8.5\r\n------------------------------------------------------------\r\n\r\nBuild time:   2023-11-29 14:08:57 UTC\r\nRevision:     28aca86a7180baa17117e0e5ba01d8ea9feca598\r\n\r\nKotlin:       1.9.20\r\nGroovy:       3.0.17\r\nAnt:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023\r\nJVM:          21.0.1 (Eclipse Adoptium 21.0.1+12-LTS)\r\nOS:           Linux 5.15.133.1-microsoft-standard-WSL2 amd64\r\n```\r\n\r\n**Docker Compose**\r\n\r\n```jshelllanguage\r\ndocker compose version\r\n    \r\nDocker Compose version v2.22.2\r\n```\r\n\r\n#### :rocket: If you don't want to bother with a local setup\r\n\r\n##### With Gitpod (recommended)\r\nYou can use [Gitpod](https://gitpod.io).\r\nYou must create an account first.\r\nYou then can open this project in either your local VS Code or directly in your browser:\r\n\r\n[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#github.com/alexandre-touret/rest-apis-versioning-workshop.git)\r\n\r\n##### With Github Codespaces\r\nYou can also [use Github Codespaces](https://docs.github.com/en/codespaces/).\r\nYou can create a new one by [running \"Code \u003e Create codespace on main\"](https://docs.github.com/en/codespaces/developing-in-codespaces/creating-a-codespace-for-a-repository#creating-a-codespace-for-a-repository).\r\n\r\nYou have then to run the command in the shell:\r\n\r\n```jshelllanguage\r\npip install httpie\r\nsdk install java 21.0.1-tem\r\nsdk default java 21.0.1-tem\r\n```\r\n\r\n## :boom: Ready ?\r\n[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#github.com/alexandre-touret/rest-apis-versioning-workshop.git)\r\n\r\n\u003e **If you fork this repo**\r\n\u003e\r\n\u003e Don't forget to change the \"Open in GitPod\" button URL:\r\n\u003e ```markdown\r\n\u003e [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#github.com/%%MY_NAMESPACE%%/rest-apis-versioning-workshop.git)\r\n\u003e ```\r\n or you can directly browse this URL (think to change the ``%%MY_NAMESPACE%%`` prefix):\r\n\r\n\u003e ``https://gitpod.io/#github.com/%%MY_NAMESPACE%%/rest-apis-versioning-workshop.git``\r\n_________________\r\n\r\n**Now, you can start [the workshop](docs/index.md) :tada:.**\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandre-touret%2Frest-apis-versioning-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandre-touret%2Frest-apis-versioning-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandre-touret%2Frest-apis-versioning-workshop/lists"}