Search code examples
pythondjangoangularapollo-clientgraphene-python

How to get cors to work properly with angular (apollo client ) and django/graphene


I am trying to build an application with python-graphene and django to persist data on the database side and using angular on the client side.

I have developed both sides and they are working well independently, angular using the in-memory-web-api and graphene using insomnia (a postman style application for linux).

To integrate them, I am trying to use apollo-angular. However, the request is returning a 404.

I am fairly new to web development, so I might be missing something trivial.

Searching online I found out that because the server is running on http://localhost:8000 and the application is running on http://localhost:4200, I needed to have CORS setup on the server side.

I have followed the instructions on the manual:

  1. Install corsheaders via pip install django-cors-headers.
  2. Add corsheaders to INSTALLED_APPS.
  3. Add corsheaders.middleware.CorsMiddleware topmost at MIDDLEWARE.

But still the error persisted.

That is when I came across this thread and the answers seemed to be relevant. so I:

  1. Added CORS_ORIGIN_ALLOW_ALL = True and CORS_ALLOW_CREDENTIALS = True to settings.py at the server.
  2. Removed django.middleware.clickjacking.XFrameOptionsMiddleware from MIDDLEWERE.
  3. Added the withCredentials header to the request at the client side.
  4. Cleaned the browser cashed data and cookies.

But still the error persisted.

Here is my component which contains the query:

import { Component, OnInit } from '@angular/core';
import { Patient } from '../patient';
import gql from 'graphql-tag';
import { Apollo } from 'apollo-angular';

const GET_PATIENTS = gql`
query all_patients {
    patients{
        id
        name
        age
    }
}
`;

export interface GetPatientsResponse {
    patients: Patient[];
    loading: boolean;
}

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
    patients: Patient[] = [];
    loading = true;

    constructor(private apollo: Apollo) { }

    ngOnInit() {
        this.apollo.watchQuery<GetPatientsResponse>({
            query: GET_PATIENTS
        }).valueChanges.subscribe((response) => {
            this.patients = response.data.patients;
            this.loading = response.data.loading;
        });
    }
}

Also, I have added these to graphql.module.ts:

const uri = 'http://localhost:8000/graphql/';

export function createApollo(httpLink: HttpLink) {
  return {
    link: httpLink.create({uri: 'http://localhost:8000/graphql/', withCredentials: true}),
    cache: new InMemoryCache(),
  };
}

I expected to receive the json from the server with the result from my query and got a 404: http://localhost:8000/graphql/ Not Found instead.

What am I missing?


Solution

  • After searching for a long time I finally discovered what was the blunder after reading this answer.

    I was using both the angular-in-memory-web-api and trying to send the requests to my own server, which was resulting in the error.

    By removing the angular-in-memory-web-api from my app.module.ts everything worked as expected.