|
| 1 | +# iot-demo |
| 2 | +This repository demonstrates tools that can solve some fundamental problems with developing REST APIs in GoLang. Mostly using code generation. |
| 3 | + |
| 4 | +## Toy Project |
| 5 | +Will keep track of device metrics in a factory. Devices will periodically send metric data. According to the metric sent by the device, we may want to make the device sound an alert. We also want to be able to see metrics sent by a given device. |
| 6 | + |
| 7 | +- Devices will be registered with serial number, registration date and a firmware version. They will be given a token on registration. |
| 8 | +- Each device will send temperature data as a double value, using the token supplied on registration. |
| 9 | +- When device sends a metric data, it may receive 'ALERT' or 'OK' message. |
| 10 | +- We want to give an alert on a certain thresholds(initially between 70-100C). We want this configurable. |
| 11 | +- We want an endpoint that accepts device id and returns metrics. |
| 12 | + |
| 13 | +## Tools Demonstrated |
| 14 | +- [wire](https://github.com/google/wire) for dependency injection with code generation |
| 15 | +- [swag](https://github.com/swaggo/swag) for documentation generation |
| 16 | +- [mockgen](https://github.com/golang/mock) for generating mock structs for interfaces |
| 17 | +- [viper](https://github.com/spf13/viper) for static/dynamic configuration. we use configmap mount with kubernetes in production. dynamic configuration works as is. |
| 18 | + |
| 19 | + |
| 20 | +## Run the Server |
| 21 | +Just run `go run iot-demo/cmd/server` to start the project. By default it listens to 8080 port. You can override it by setting the PORT env variable. |
| 22 | + |
| 23 | +## Dependencies |
| 24 | +To install dependencies used by the project, run `go mod download`. There are also some global dependencies that you may need to install to make `go generate ./...` run. Those are: |
| 25 | + |
| 26 | +``` |
| 27 | +# for di |
| 28 | +go get github.com/google/wire/cmd/wire |
| 29 | +# for test mocks |
| 30 | +go get github.com/golang/mock/gomock |
| 31 | +go install github.com/golang/mock/mockgen |
| 32 | +# install swag for doc generation |
| 33 | +go get github.com/swaggo/swag/cmd/swag |
| 34 | +``` |
| 35 | + |
| 36 | +## Environment Variables |
| 37 | +- `PROFILE` decides which environments configurations should override default configuration. Could be dev/stage/prod. |
| 38 | +- `GO_ENV` can be production. Controls the `IsRelease` flag in global configuration. |
| 39 | +- `PORT` decides which port to start the server on. |
| 40 | + |
| 41 | +## Project Structure |
| 42 | +``` |
| 43 | +. |
| 44 | +├── adapters # implementation details |
| 45 | +│ ├── config # static/dynamic config reading with viper |
| 46 | +│ ├── http # REST HTTP API with gin, documented with swag |
| 47 | +│ ├── jwt # jwt creation/parsing with jwt-go |
| 48 | +│ └── storage # in memory repository functions (NOT THREAD SAFE!) |
| 49 | +├── mocks # test struct mocks for interfaces |
| 50 | +├── resources # configuration files |
| 51 | +│ ├── config.yaml # static configuration file |
| 52 | +│ └── config_dynamic.yaml # dynamic configuration file that will be re-read on changes |
| 53 | +├── cmd |
| 54 | +│ └── server # server entry point with wire |
| 55 | +└─── pkg # business logic |
| 56 | + ├── auth |
| 57 | + ├── device |
| 58 | + │ ├── add-device # device registration use-case |
| 59 | + │ └── registry # device CRUD service |
| 60 | + └── metrics |
| 61 | + ├── query-metrics # metric query use-case |
| 62 | + ├── add-metrics # metric insert use-case |
| 63 | + ├── ingestion # metric CRUD service |
| 64 | + └── alert # threshold alert business logic |
| 65 | +
|
| 66 | +``` |
| 67 | + |
| 68 | +## Some Questions Related to the Structure |
| 69 | +- Is it okay to put the mocks under `/mocks`. Any better place to put it? |
| 70 | +- `adapters` folder includes implementation details of config/auth/http/repository. Should they be put under `/pkg` if so where? Putting them side by side with business logic, makes code harder to navigate. |
| 71 | +- Better way of naming business logic related packages? Package under `/pkg/device/registry` is named `registry`. should it be named something else? |
| 72 | + |
0 commit comments