Solution proposal with microservice oriented architecture. The mobile application is implemented by React Native and in it users can search for nearby restaurants according to the GPS coordinate.
The backend architecture depends on a network of microservices that communicate through GraphQL for external access, Grpc for internal back-end communications and NATS for asynchronous communication processes.
The infrastructure was implemented with Terraform, using recipes associated with the implementation of a Kubernetes cluster through the Azure Kubernetes Service (AKS). On the other hand, there is also a service mesh implemented in Linkerd that allows you to manage package tracking between microservices, service logs, infrastructure metrics with Prometheus/Grafana and other things.
It is possible to use Skaffold to run a cluster through Minikube. In this way, each functionality will be tested in the most similar way to the production environment.
See Architecture and Application screenshots at the ./docs/images
folder.
The solution is composed of 5 microservices written in various languages. The main repository (where we are now) is a monorepo but each of the services has its respective repository and everything is linked through the Git sub-modules.
Find Protocol Buffers Descriptions at the ./lib/proto/demo.proto
file.
Service | Language | Description |
---|---|---|
Mobile App | Javascript | Mobile application with login, signup, search and history screens. |
Gateway Service | Typescript | service that acts as a 'data aggregation layer' through GraphQL. Through it you can access the resources provided by the back-end microservices. |
Users Service | Golang | Microservice implemented in Golang that stores user information into postgres DB. |
Auth Service | Golang | Microservice implemented in Typecript that allows authenticating access to the backend through a JWT token. On the other hand, it manages user signup and login. |
Restaurants Service | Golang | Microservice implemented in Golang that get nearby restaurants from Google Places API. |
History Service | Golang | The microservice implemented in Golang saves the history associated with searches performed in the restaurant service. |
NATS Server | - | NATS is an open-source, high-performance, cloud native messaging system. |
- GraphQL Backend: http://tenpo-aks-ingress.centralus.cloudapp.azure.com/graphql
- Mobile: https://expo.io/@cagodoy/tenpo-mobile-app
- Linkerd Dashboard: http://localhost:50750
- Clone repo:
git clone [email protected]:cagodoy/tenpo-challenge.git
. - Prepare all repos with
make prepare
command.
make compose
: start docker-compose in local with all services.make stop
: stop docker-compose.
brew install skaffold
: install skaffold dependency.brew install kubectl
: install kubectl cli.brew install minikube
: install minikube.minikube start
: start minikube.skaffold run
: start skaffold.
- Configure Terraform with azure in our machine. [Link]
- Set up Azure storage to store Terraform state. [Link]
- Run
az storage container create -n tfstate --account-name <YourAzureStorageAccountName> --account-key <YourAzureStorageAccountKey>
- Run
terraform init -backend-config="storage_account_name=<YourAzureStorageAccountName>" -backend-config="container_name=tfstate" -backend-config="access_key=<YourStorageAccountAccessKey>" -backend-config="key=codelab.microsoft.tfstate"
- Configure ENV values in shell:
export TF_VAR_client_id=<service-principal-appid>
export TF_VAR_client_secret=<service-principal-password>
- Run inside
./infra/terraform
the following commands.terraform plan -out out.plan
for generate tf plan file. (Wait 3 minutes approximately)terraform apply out.plan
for apply plan directly azure provider. (Wait 15 minutes approximately)
- Check cluster with
kubectl get nodes
. - Configure Static Ip to use with HTTPS. [Link]
- Run inside
./infra/kubernetes
the following commands.kubectl apply -f ingress
for deployyaml
ingress files.kubectl apply -f services
for deployyaml
services files.
brew install linkerd
: install linkerd dependency.linkerd check --pre
: checks to determine if the control plane can be installed on our cluster.linkerd install | kubectl apply -f -
: install Linkerd to cluster.kubectl get svc/pod --namespace linkerd --output wide
: confirm that the svc/pod resources are created.linkerd check
: check cluster before Linkerd installation.kubectl get deploy -o yaml | linkerd inject - | kubectl apply -f -
: inject all the deployments in the default namespace.linkerd dashboard
: open linkerd web dashboard.
- Implements CI/CD for each service. (check
/src
folder) - Integration test for
auth
service for check GraphQL responses. - Integration test for
restaurants
service for check GraphQL responses. - Integration test for
history
service for check GraphQL responses.