yung peso
yung peso

Reputation: 1766

Django / React - Production API URL routing issues

I have a backend Django REST API that also helps serve my React frontend. I currently have an issue with my API requests url paths to my Django API in production for every page except my home page...

API URL's that work:

I'm able to visit my home page, within my home page, I have a GET request to my API which works great and loads data as expected. This is the only working GET request of my website because the API URL path is correct to my urlpatterns syntax.

API URL's that DON'T work:

The issues arise when I visit a page OTHER than the home page of my React app. My API requests to Django on other pages are using the wrong URL path according to my network panel (they are also responding with index.html), which has me believe I set up my django URLs wrong.

Please checkout my configuration below:

main urls.py:

def render_react(request):
    return render(request, "index.html") #<---- index.html from React

    
urlpatterns = [
   path('auth/', include('drf_social_oauth2.urls', namespace='drf')),
   path('admin/', admin.site.urls),
   path('api/', include('bucket_api.urls', namespace='bucket_api')),
   path('api/user/', include('users.urls', namespace='users')),
   path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

urlpatterns += [
   re_path('',render_react)  #<---- Serving React index.html
]

Here is an example of the issue:

When I visit this subpage URL:

https://mywebsite.com/try-demo/ra4r7n7mdb 

A GET request should be firing off too this URL:

https://mywebsite.com/api/demo/ra4r7n7mdb 

However instead of sending the request to the correct URL above, it's sending to this url:

https://mywebsite.com/try-demo/api/demo/ra4r7n7mdb 

This is the same problem for other parts of my website that are requesting data from my django api. So when I visit my login page (https://mywebsite.com/login), and enter my details to request an authentication token. The request for the token should be:

https://mywebsite.com/auth/token/ 

but instead its requesting the data through this:

https://mywebsite.com/login/auth/token/ 

How to fix this?

my url patterns has a catch all request, my react is then able to 404 pages that don't exist. The only problem I have is how my React app is requesting data to my API in production. (again the API request on my homepage works fine) Why are my other requests appending the first URL path of my React router URL's?

I don't want to clog this post with code, so please let me know what other information I should present here to help solve this problem?


UPDATE

I have solved the API request issues to my server. The paths are now correct according to the network panel. However, the issue still remains where I seem to be only getting my index.html as the response for these API requests (they should be data responses, not index.html)

Here is my catch all regex for Django

   re_path(".*/", render_react),
   re_path(r"^$", render_react) 

NEW EDIT

I am now able to get one of my API data requests to respond with JSON data (as should be expected) Here is the URL of the API request that works:

https://mywebiste.com/api/demo/idoyem1l4k/

These still don't work:

https://mywebsite.com/api/demo/tabledata/idoyem1l4k

https://mywebsite.com/api/demo/graphdata/idoyem1l4k


How I make requests:

import axios from 'axios';

const baseURL = `https://mywebsite.com/api`;

const axiosInstance = axios.create({
    baseURL: baseURL,
    timeout: 9000,
    headers: {
        Authorization: 'Bearer ' + localStorage.getItem('access_token'),
        'Content-Type': 'application/json',
        accept: 'application/json',
    },
});

export const getData = async (dispatch, slug, cancelToken) =>
{
  try
  {
    console.log('fired demo request')
    const response = await axiosInstance.get("demo/graphdata/" + slug, { cancelToken });
    dispatch({ type: 'FETCH_SUCCESS', payload: response.data });
  } catch (err)
  {
    if ('isCancel' in err && err.isCancel())
    {
      return;
    }

    dispatch({ type: 'FETCH_ERROR' });
  }
}

How can I return the actual data requested instead of my index?

Upvotes: 4

Views: 747

Answers (1)

ChrisRob
ChrisRob

Reputation: 1552

It makes sense, that it always returns the index.html. Your catch all regex prevents your API calls to be called, so it always resolves to render_react. I think you have 3 options.

  1. You try to put the catch-all patterns to the bottom of all urlpatterns - I'm not sure how reliable this is though
  2. You do not catch all by deleting re_path(".*/", render_react), and explicitly name every react page you want to use
  3. You change the catch-all regex to exclude your Django apps with something like re_path("(?!api).*/", render_react),

I would choose option 2, as it gives you most control of your urls

Upvotes: 2

Related Questions