Render template with params from another app (microservice)

Viewed 72

I'm making a web app with a microservice architecture. When it comes to login I want to redirect the successfully logged in user to his dashboard (which is on another microservice). I have a problem with passing parameters such as name, surname, email, and token.

microservice 1 (views.py):

class SignInView(viewsets.ViewSet):
    def post(self, request):
        email = request.data['email']
        password = request.data['password']
        user = User.objects.filter(email=email).first()
        print(bool(user.is_coordinator))
        if user is None:
            messages.error(request, 'User not found. Please try again')
            return HttpResponseRedirect('/sign-in')

        if not user.check_password(password):
            messages.error(request, 'Invalid password. Please try again')
            return HttpResponseRedirect('/sign-in')

        payload = {
            'id': user.id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=60),
            'iat': datetime.datetime.utcnow()
        }

        token = jwt.encode(payload, 'secret', algorithm='HS256')

        response = Response()
        response.set_cookie(key='jwt', value=token, httponly=True)
        response.data = ({
            'jwt': token
        })

        if user.is_coordinator:
            return redirect('http://127.0.0.1:8001/dashboard-coordinator')
        else:
            return HttpResponseRedirect('http://127.0.0.1:8001/dashboard-employee', {'name': user.name, 'surname': user.surname, 'email': user.email, 'response.data': response.data})
...

microservice 2 (views.py):

class HomeView(viewsets.ViewSet):
    def get(self, request):
        return render(request, 'dashboard-employee.html', {'name': name, 'surname': surname, 'email': email, 'response.data': response.data})

What I've included in microservice 2 does not work. How can I get and process params from microservice 1? Is there any better solution/approach?

1 Answers

The Python context of these two microservices is not directly shared, but it wouldn't be shared in the way microservice 2 needs it right now, even if the get() and the post() were in the same microservice. Set aside the microservices and HTTP for a moment and imagine if we had these two functions side by side:

def post():
    name = 'First'
    surname = 'Last'
    return get()

def get():
    return name, surname

We would get a NameError, because name and surname don't exist inside the scope of the get() function. So, how could we fix this? We could set up some sort of global state, but that's not necessary. Instead, we can pass some information from post() to get():

def post():
    name = 'First'
    surname = 'Last'
    data = {'name': name, 'surname': surname}
    return get(data)

def get(data):
    return data['name'], data['surname']

This is of course a silly example, but maybe you can already see the similarities between it and your real-world code. You have actually already done the work in put() to transmit the data, now in get() you need to grab it back out from request.query_params:

class HomeView(viewsets.ViewSet):
    def get(self, request):
        name = request.query_params['name']
        surname = request.query_params['surname']
        email = request.query_params['email']
        response_data = request.query_params['response.data']
        return render(request, 'dashboard-employee.html', {'name': name, 'surname': surname, 'email': email, 'response.data': response_data})

Or more simply,

class HomeView(viewsets.ViewSet):
    def get(self, request):
        return render(request, 'dashboard-employee.html', request.query_params)
Related