{"id":29902738,"url":"https://github.com/anders617/michigan-dining-api","last_synced_at":"2026-04-18T19:33:38.136Z","repository":{"id":74693805,"uuid":"213945764","full_name":"anders617/michigan-dining-api","owner":"anders617","description":"API Service For The University of Michigan Dining Hall Menus","archived":false,"fork":false,"pushed_at":"2023-10-21T16:59:06.000Z","size":209,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-01T16:42:26.219Z","etag":null,"topics":["api","bazel","dining","dining-halls","food","heroku","meal","michigan-dining","michigan-dining-api","service","umich","university","university-of-michigan"],"latest_commit_sha":null,"homepage":"https://michigan-dining-api.tendiesti.me","language":"Go","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/anders617.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-10-09T14:50:25.000Z","updated_at":"2025-01-20T05:21:44.000Z","dependencies_parsed_at":"2023-02-25T07:46:16.248Z","dependency_job_id":"1505eb43-0f02-4d93-b2e1-56157c474726","html_url":"https://github.com/anders617/michigan-dining-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/anders617/michigan-dining-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anders617%2Fmichigan-dining-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anders617%2Fmichigan-dining-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anders617%2Fmichigan-dining-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anders617%2Fmichigan-dining-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anders617","download_url":"https://codeload.github.com/anders617/michigan-dining-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anders617%2Fmichigan-dining-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31982743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T17:30:12.329Z","status":"ssl_error","status_checked_at":"2026-04-18T17:29:59.069Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","bazel","dining","dining-halls","food","heroku","meal","michigan-dining","michigan-dining-api","service","umich","university","university-of-michigan"],"created_at":"2025-08-01T16:12:20.906Z","updated_at":"2026-04-18T19:33:38.071Z","avatar_url":"https://github.com/anders617.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# michigan-dining-api\n[![Build Status](https://travis-ci.org/anders617/michigan-dining-api.svg?branch=master)](https://travis-ci.org/anders617/michigan-dining-api)\n\n[michigan-dining-api.tendiesti.me](https://michigan-dining-api.tendiesti.me/) \\\n[michigan-dining-api.herokuapp.com](https://michigan-dining-api.herokuapp.com/)\n\nA system for scraping and serving information from the University of Michigan dining API. This repository contains the code for fetching, analyzing and serving dining information. For how to make use of this service, see the [usage](#Usage) section or visit the [mdining-proto](https://github.com/anders617/mdining-proto) repository for protobuf service definitions.\n\n\nData is scraped from the University of Michigan's MDining API, formatted and stored in a database to\nbe served.\nThis allows for data structures and formats that are easier to work with than the original API and\nfor historical\ndata to be retrieved past what the MDining API offers (2019-11-02 is the earliest date available\nthrough the tendies time michigan dining api service).\nCheck out \u003ca href=\"https://tendiesti.me/stats\"\u003ethe MDining statistics page of tendies time\u003c/a\u003e for\nexamples made using this historical data.\n\n**[Setup](#Setup)** \\\n**[Executables](#Executables)** \\\n**[Deployment](#Deployment)** \\\n**[Usage](#Usage)** \n\n## Setup\nClone this repo\n```shell\ngit clone https://github.com/anders617/michigan-dining-api.git\n```\n\nInstall the [Bazel](https://docs.bazel.build/versions/master/install.html) build system\n\n## Executables\nThis project uses the [glog](https://github.com/golang/glog) library for logging. The `--alsologtostderr` flag can be specified to send log output to stderr.\n\nRun the web server:\n```shell\nbazel run //cmd:web -- --alsologtostderr\n```\n\nRun the fetch executable to fill the DiningHalls/Foods/Menus tables:\n```shell\nbazel run //cmd:fetch -- --alsologtostderr\n```\n\nRun the analyze executable to fill the FoodStats table (depends on data from running `//cmd:fetch` above):\n```shell\nbazel run //cmd:analyze -- --alsologtostderr\n```\n\nRun the db executable to create tables:\n```shell\nbazel run //cmd:db -- --alsologtostderr --create\n```\n\nRun the db executable to delete tables:\n```shell\nbazel run //cmd:db -- --alsologtostderr --delete\n```\n\nRun the testing client executable to connect to a instance of the web server:\n```shell\nbazel run //cmd:client -- --alsologtostderr --address=michigan-dining-api.tendiesti.me:443 --use_credentials\n```\n\n## Deployment\n**[Containers](#Containers)** \\\n**[AWS](#AWS)** \\\n**[Heroku](#Heroku)**\n### Containers\nThe `//cmd:web`, `//cmd:fetch`, and `//cmd:analyze` executables all have rules for creating [distroless](https://github.com/GoogleContainerTools/distroless) docker images:\n* `//cmd/web:web_image` \n* `//cmd:fetch:fetch_image` \n* `//cmd:analyze:analyze_image`\n\nThere are also rules for pushing these container images to container registries:\n* `//cmd/web:web_image_publish`\n* `//cmd/fetch:fetch_image_publish`\n* `//cmd/analyze:analyze_image_publish`\n\nNote that each target above needs to be run with the `--platforms=@io_bazel_rules_go//go/toolchain:linux_amd64` flag set to ensure the binaries are built for running in a linux container. Alternatively, you can specify `--config=container` to use the config set in the `.bazelrc` to avoid having to remember the long platform name.\n\nCurrently these rules are configures to push the images to gcr.io/michigandiningapi but can be easily configured to publish to other container registries by editing the rules in the BUILD files.\n\nThis means that the latest container image builds for each executable are available at:\n* gcr.io/michigandiningapi/web:latest\n* gcr.io/michigandiningapi/fetch:latest\n* gcr.io/michigandiningapi/analyze:latest\n\nNote that these container images need to have the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` set when run for the AWS account which will host the dynamodb data tables.\n\nNote that since these are distroless docker images, only the bare minimum for running the executable is included so no shells or other standard Linux programs are included. This means that traditional Docker healthchecks that depend on shell commands will not work and should not be used for determining container health.\n### AWS\nCurrently michigan-dining-api is deployed and hosted on [AWS](https://aws.amazon.com/) using the [Elastic Container Service](https://aws.amazon.com/ecs/) at [michigan-dining-api.tendiesti.me](https://michigan-dining-api.tendiesti.me).\n\nThere is a [task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-task-definition.html) for each executable container image (listed above). Within each task definition, the `AWS_SECRET_ACCESS_KEY` and `AWS_SECRET_ACCESS_KEY` environment variables must be specified for the AWS account hosting the dynamodb tables. The analyze and web tasks have 0.5GiB memory and 0.25vCPU allocated. The fetch task requires more memory and is allocated 1.0GiB memory and 0.25vCPU.\n\nThere is a [Service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html) defined for the web server using the web task definition. This service is deployed on a [Fargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html) cluster. The web service is configured to include [load balancing](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html) using a [network load balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html). The network load balancer is configured with an SSL/TLS certificate on its :443 listener and decrypts HTTPS traffic before it is forwarded to the web server. It is important this is a network load balancer instead of an application load balancer since AWS application load balancers do not handle grpc style HTTP/2 traffic correctly.\n\nThere are [scheduled tasks](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/scheduled_tasks.html) for the fetch and analyze tasks to run once daily in order to update the dynamodb tables.\n\n### Heroku\nCurrently michigan-dining-api is deployed and hosted on [Heroku](https://www.heroku.com/home) at https://michigan-dining-api.herokuapp.com.\n\nHeroku is not optimal for hosting grpc servers since it does not support HTTP/2. Therefore, if you plan to take advantage of grpc, I recommend you use a different provider such as AWS.\n\nIn order to deploy your own server:\n* Setup the Heroku application to point to this repository\n* Add the custom [heroku-buildpack-bazel](https://github.com/anders617/heroku-buildpack-bazel) buildpack to allow building with bazel\n* Setup the [HerokuScheduler](https://devcenter.heroku.com/articles/scheduler) add on to run the command `cmd/fetch/fetch`  and `cmd/analyze/analyze` daily in order to fill the data tables\n* Set the following Heroku config vars:\n    * `AWS_ACCESS_KEY_ID` - Access key used for AWS DynamoDB access\n    * `AWS_SECRET_ACCESS_KEY` - Secret used for AWS DynamoDB access\n    * `BAZEL_BUILD_PATH` - `//cmd:all`\n    * `BAZEL_VERSION` - `1.1.0` (or later version)\n    * `BUILD_CACHE_LOCATION` - Address of a bazel remote cache server (optional)\n* Go to the deploy tab and click deploy branch\n\n## Usage\nThere are examples of grpc usage and client libraries in the [mdining-proto](https://github.com/anders617/mdining-proto) library. This library also contains the proto definitions of messages and services provided by this service.\n### REST Endpoints\nYou can try out the following queries to get a sense of what is available through the api. \\\nAdditionally, \u003ca href=\"https://michigan-dining-api.tendiesti.me/\" \u003ethe homepage for the tendies time michigan dining api service\u003c/a\u003e has longer descriptions of the purpose of each query.\n\n[/v1/items](https://michigan-dining-api.tendiesti.me/v1/items) \\\n[/v1/diningHalls](https://michigan-dining-api.herokuapp.com/v1/diningHalls) \\\n[/v1/filterableEntries](https://michigan-dining-api.tendiesti.me/v1/filterableEntries) \\\n[/v1/all](https://michigan-dining-api.tendiesti.me/v1/all) \\\n[/v1/menus?date={yyyy-MM-dd}\u0026diningHall={DINING_HALL}\u0026meal={MEAL}](https://michigan-dining-api.tendiesti.me/v1/menus?date=2019-11-04\u0026diningHall=Bursley%20Dining%20Hall\u0026meal=LUNCH) \\\n[/v1/foods?name={LOWERCASE_FOOD_NAME}\u0026date={yyyy-MM-dd}\u0026meal={MEAL}](https://michigan-dining-api.tendiesti.me/v1/foods?name=chicken%20tenders\u0026date=2019-11-08\u0026meal=DINNER) \\\n[/v1/summarystats](https://michigan-dining-api.tendiesti.me/v1/summarystats) \\\n[/v1/stats](https://michigan-dining-api.tendiesti.me/v1/stats) \\\n[/v1/hearts](https://michigan-dining-api.tendiesti.me/v1/hearts?keys=chicken%20tenders)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanders617%2Fmichigan-dining-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanders617%2Fmichigan-dining-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanders617%2Fmichigan-dining-api/lists"}