{"id":17855600,"url":"https://github.com/nebrius/workshop-dinojs-2018","last_synced_at":"2026-01-16T00:52:09.033Z","repository":{"id":75506693,"uuid":"137778267","full_name":"nebrius/workshop-dinojs-2018","owner":"nebrius","description":"Serverless workshop materials for DinosaurJS 2018","archived":false,"fork":false,"pushed_at":"2018-06-22T14:52:38.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-08T08:46:59.127Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","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/nebrius.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":"2018-06-18T16:32:49.000Z","updated_at":"2018-06-22T14:52:40.000Z","dependencies_parsed_at":"2023-06-06T16:45:20.076Z","dependency_job_id":null,"html_url":"https://github.com/nebrius/workshop-dinojs-2018","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/nebrius%2Fworkshop-dinojs-2018","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nebrius%2Fworkshop-dinojs-2018/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nebrius%2Fworkshop-dinojs-2018/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nebrius%2Fworkshop-dinojs-2018/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nebrius","download_url":"https://codeload.github.com/nebrius/workshop-dinojs-2018/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246866099,"owners_count":20846496,"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":[],"created_at":"2024-10-28T02:23:45.130Z","updated_at":"2026-01-16T00:52:08.998Z","avatar_url":"https://github.com/nebrius.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DinosaurJS 2018 Serverless Workshop\n\nWelcome to the Serverless Design workshop at DinosaurJS 2018!\n\nIn this workshop, we'll be using [Azure Functions](https://azure.microsoft.com/en-us/services/functions/) to create a simple but functional serverless application. We have Azure credits to give everyone, if you did not receive an Azure pass, please request one from the Bryan Hughes, workshop instructor.\n\n## Part 1: Hello World\n\nFor this first section, Bryan will lead you step by step through creating a hello world example in Azure Functions. We'll create a function that takes in a name in an HTTP query, and returns a JSON response saying hi.\n\n## Part 2: Adding a Database\n\nFor this section, Bryan will lead you step by step through adding a [Cosmos DB](https://azure.microsoft.com/en-us/services/cosmos-db/) database to store a list of dinosaurs, and return the list to a user in JSON.\n\n## Part 3: Moar Functions!\n\nFor this self-guided section, you will modify your first function and implement two new function to serve as the back-end for the front-end implemented at [index.html](index.html). You can load this front-end directly from your filesystem, there is no need to use an HTTP server to host it. Just make sure to set CORS to `*` in the Azure Portal!\n\nThis frontend allows you to view all dinosaurs in the list, including a photo of the dinosaur, and to add new ones. Specifically, you will need to implement two HTTP endpoints that the front-end will call.\n\n## PUT /api/items Function\n\nThe first endpoint is completely new, and will allow us to create items and store them in Cosmos DB.\n\nThe request body should have the following structure:\n\n```\nPUT /api/items\n{\n  name: string;\n  type: string;\n  imageURL: string;\n}\n```\n\nNote that we have added a new field here called `imageURL`. This field allows users to specify a URL to an image (e.g. https://upload.wikimedia.org/wikipedia/commons/f/fb/Stegosaurus_stenops_sophie_wiki_martyniuk.png). This url should be stored in the database along with the rest of the dinosaur's information.\n\n### GET /api/items Function\n\nThe next endpoint is a slight modification of the `/api/hello` endpoint function we created in the previous section.\n\nThe response body should have the following structure:\n\n```\nGET /api/items\n[{\n  id: string;\n  name: string;\n  type: string;\n  image: string; // Base 64 encoded image data URI\n}, ... ]\n```\n\nMost of this is the same as before, but note how we have added a new field called `image` that contains a [Base 64 encoded data URI](https://css-tricks.com/data-uris/) version of the image found at the URL specified above for the dinosaur.\n\nThere is an extra requirement for this excercise involving images: you must fetch it from another Azure Function. You should use the [request](https://www.npmjs.com/package/request) module from npm to make an HTTP GET request to the Azure Function at `GET /api/image/?url=${imageURL}`.\n\nFor bonus points, add a cache to this Azure Function so that you only have to call the other Azure Function once per url. You can do this using a JavaScript [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) or a plain old JavaScript object. You should use the image URL as the key.\n\n## Image Fetch Function\n\nThis Azure Function is the image helper function that was mentioned above, and will exist at `GET /api/image/?url=${imageURL}`. The return value will be the data URI encoded version of the image. Take care that you get the correct header for the correct file type in the data URI, e.g. `data:image/png;base64,` for a PNG.\n\nFor bonus points, add a cache to this Azure Function that behaves like the cache in the other Azure Function. You might be asking yourself \"why would I cache in both places?\" In a normal monolith application, there wouldn't be a need, but it can be needed here! If, for example, the GET function that calls this one goes cold while this one is hot, the GET function's cache would be empty, but this one wouldn't be.\n\n## Stretch Goals\n\n### Bundling\n\nOnce you've implemented your Azure Functions and gotten everything working correctly, let's improve cold-start time by using [Azure Function Pack](https://github.com/Azure/azure-functions-pack) to bundle your source and dependencies into a single file.\n\n### Debugging\n\nConsole debugging can only get us so far, and Azure Functions has a number of tools for using a debugger in Visual Studio and Visual Studio Code.\n\nFor Visual Studio Code, insteall the Azure extension and follow the instructions at https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions to set up debugging for Azure Functions\n\n# License\n\nMIT License\n\nCopyright (c) 2018 Bryan Hughes \u003cbryan.hughes@microsoft.com\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnebrius%2Fworkshop-dinojs-2018","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnebrius%2Fworkshop-dinojs-2018","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnebrius%2Fworkshop-dinojs-2018/lists"}