{"id":19425134,"url":"https://github.com/krzemin/endpoints-scala-workshop","last_synced_at":"2025-04-24T16:31:32.860Z","repository":{"id":151657870,"uuid":"165071981","full_name":"krzemin/endpoints-scala-workshop","owner":"krzemin","description":"Materials for endpoints Scala library workshop","archived":false,"fork":false,"pushed_at":"2019-09-16T11:53:37.000Z","size":2287,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-03T07:51:19.106Z","etag":null,"topics":["endpoints","scala","workshop"],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/krzemin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-01-10T14:15:24.000Z","updated_at":"2020-12-10T07:56:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"e381c8a1-4329-410d-8159-f80abcbab9cd","html_url":"https://github.com/krzemin/endpoints-scala-workshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krzemin%2Fendpoints-scala-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krzemin%2Fendpoints-scala-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krzemin%2Fendpoints-scala-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krzemin%2Fendpoints-scala-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krzemin","download_url":"https://codeload.github.com/krzemin/endpoints-scala-workshop/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250663544,"owners_count":21467366,"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":["endpoints","scala","workshop"],"created_at":"2024-11-10T13:46:31.483Z","updated_at":"2025-04-24T16:31:32.853Z","avatar_url":"https://github.com/krzemin.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# endpoints-scala-workshop\nMaterials for endpoints Scala library workshop\n\nThere are few exercises in this repository that aims to\nget you familiar with Scala [endpoints](http://julienrf.github.io/endpoints/)\nlibrary.\n\nPresentation is at https://docs.google.com/presentation/d/19ob9ZYwtm6qM5Jwg_AXHY-VGjW-DXjAHPStDvuLuyW4/edit#slide=id.p\n\n### Pizza Store\n\nYou are given few data types that describe simple pizza store service,\nwhere you can manage list of pizza menu entries, their ingredients\nand prices, depending on their size.\n\n\n```scala\ncase class Pizza(id: Int,\n                 name: String,\n                 ingredients: List[String],\n                 variants: List[Variant])\n\ncase class Variant(size: Size,\n                   price: Price)\n\nsealed trait Size\ncase object Small extends Size\ncase object Medium extends Size\ncase object Big extends Size\n\ncase class Price(amount: BigDecimal,\n                 currency: String)\n```\n\nClass `pizzastore.Repository` contains simple, in-memory implementation of pizza menu\nthat is used in this workshop.\n\n#### Running server and test client\n\nIn order to run the server, you need to invoke `sbt run`. Api and documentation (previewed with swagger ui)\nshould be available at http://localhost:5000.\n\nIn order to run the [test client example program](src/test/scala/pizzastore/TestClient.scala), you need to\nhave server that is up. Then invoke `sbt test:run` to execute test program against the server.\n\n\n### Exercise 1 - API endpoints for ingredients management\n\nDefine 3 following API endpoints:\n\n* `GET /pizzas/\u003cid\u003e/ingredients` - it should return ingredients of specified pizza as JSON list\n* `PUT /pizzas/\u003cid\u003e/ingredients` - it should upsert ingredient to specified pizza\n* `DELETE /pizzas/\u003cid\u003e/ingredients/\u003cname\u003e` - it should delete specified ingredient in specified pizza\n\nModify `TestClient` to make Hawai pizza ingredients update with these 3 endpoints.\n\n\n### Exercise 2 - Support 404 errors correctly\n\nNote that trying to access pizza by non-existing `id`, the exception will be thrown.\nThis is because `pizzastore.Repository` has some defect. You need to fix this defect, but the fix\nalso affects return type of few methods.\n\nOnce you modify repository type signatures, they don't match to the signatures required\nby the server implementation. On the other hand, we would like to return 404 response codes\nexplicitly for non-existing resources (instead of 500 signalling some case not handled properly).\n\nWith endpoints, you don't control response codes from server implementation! For such use cases you need\nalgebra that allows you to explicitly express value optionality. Hopefully, endpoints come with\nstandard response operation `wheneverFound` (or `.orNotFound` extension method).\nSee https://github.com/julienrf/endpoints/blob/master/algebras/algebra/src/main/scala/endpoints/algebra/Responses.scala\n\nAs a part of the task, write a test using the client that demonstrates that when trying\nnon-existing pizzas, client returns `None`.\n\nWhat about OpenAPI documentation?\n\n\n### Exercise 3 - Validation algebra\n\nOk, let's add few requirements to our API. Adding or updating pizza with empty name is not nice.\nSimilarly, we shouldn't allow pizzas with empty ingredients list to be present in our store. Let's add\nsome validation to our `PUT /pizzas` endpoint!\n\nThe endpoint should:\n- upsert only pizzas with non-empty name and ingredient list, returning 200 response code\n- return json containing list of problems, with 422 response code\n\nFor example:\n```\nPUT /pizzas\n{\n  \"id\": 6,\n  \"name\": \"\",\n  \"ingredients\": []\n  \"variants\": []\n}\n```\n\nshould return\n```\nHTTP/422\n[\n  \"name is empty!\",\n  \"ingredients list is empty!\"\n]\n```\n\nAdditional validation rules are up to you :)\n\nWrite the test using generated client, that verifies your validation. Make sure\nthe documentation is aligned, so that it mentions 422 code as validation error.\n\n\n### Exercise 4 - Authentication\n\nIt's time to secure our API!\n\nIn this task you need to make sure, that endpoints modifying content of the store\n(`PUT`, `POST`, `DELETE`) are secured by HTTP Basic Authentication. To perform this\ntask, `endpoints.algebra.BasicAuthentication` might be useful.\n\nAs usually:\n- make sure that you write test that invokes secured endpoints without\n  credentials and you get appropriate http status code\n- make sure the docs reflect security mechanism for secured endpoints\n\n### Solutions\n\nIf you stuck at some exercise or want to see my solution, you can view it on `exercise-n` branch.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrzemin%2Fendpoints-scala-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrzemin%2Fendpoints-scala-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrzemin%2Fendpoints-scala-workshop/lists"}