Skip to content

Commit

Permalink
Add trailing slash to the graphql URLs (#3389)
Browse files Browse the repository at this point in the history
  • Loading branch information
mathjazz authored Sep 30, 2024
1 parent fbeb09b commit 6a8744b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 27 deletions.
14 changes: 7 additions & 7 deletions pontoon/api/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# GraphQL API

Pontoon exposes some of its data via a public API endpoint. The API is
[GraphQL](http://graphql.org/)-based and available at `/graphql`.
[GraphQL](http://graphql.org/)-based and available at `/graphql/`.

## Production Deployments

Expand All @@ -12,13 +12,13 @@ the query must be escaped.
An example GET requests may look like this:

```bash
$ curl --globoff https://example.com/graphql?query={projects{name}}
$ curl --globoff "https://example.com/graphql/?query={projects{name}}"
```

An example POST requests may look like this:

```bash
$ curl -X POST -d "query={ projects { name } }" https://example.com/graphql
$ curl -X POST -d "query={ projects { name } }" https://example.com/graphql/
```

## Local Development
Expand All @@ -33,23 +33,23 @@ a production one, returning JSON responses.
The following query in the CLI will return a JSON response:

```bash
$ curl --globoff http://localhost:8000/graphql?query={projects{name}}
$ curl --globoff "http://localhost:8000/graphql/?query={projects{name}}"
```

If however a request is sent with `Accept: text/html` such as is the case when
accessing the endpoint in a browser, a GUI query editor and explorer,
[GraphiQL](https://github.com/graphql/graphiql), will be served::

http://localhost:8000/graphql?query={projects{name}}
http://localhost:8000/graphql/?query={projects{name}}

To preview the JSON response in the browser, pass in the `raw` query argument::

http://localhost:8000/graphql?query={projects{name}}&raw
http://localhost:8000/graphql/?query={projects{name}}&raw

## Query IDE

The [GraphiQL](https://github.com/graphql/graphiql) query IDE is available at
`http://localhost:8000/graphql` when running Pontoon locally and the URL is
`http://localhost:8000/graphql/` when running Pontoon locally and the URL is
accessed with the `Accept: text/html` header, e.g. using a browser.

It offers a query editor with:
Expand Down
16 changes: 8 additions & 8 deletions pontoon/api/tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_projects(client):
}"""
}

response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

ProjectFactory.create(visibility=Project.Visibility.PRIVATE)
assert response.status_code == 200
Expand Down Expand Up @@ -111,7 +111,7 @@ def test_project_filters(
}
if is_admin:
client.force_login(admin)
response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

assert response.status_code == 200
assert response.json() == {
Expand Down Expand Up @@ -143,7 +143,7 @@ def test_project_localizations(client):
}"""
}

response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

assert response.status_code == 200
assert response.json() == {
Expand Down Expand Up @@ -205,7 +205,7 @@ def test_localization_filters(
if is_admin:
client.force_login(admin)

response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

assert response.status_code == 200
assert response.json() == {
Expand Down Expand Up @@ -246,7 +246,7 @@ def test_projects_localizations_cyclic(client):
}"""
}

response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

assert response.status_code == 200
assert b"Cyclic queries are forbidden" in response.content
Expand All @@ -268,7 +268,7 @@ def test_project_localizations_cyclic(client):
}"""
}

response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

assert response.status_code == 200
assert b"Cyclic queries are forbidden" in response.content
Expand All @@ -290,7 +290,7 @@ def test_locales_localizations_cyclic(client):
}"""
}

response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

assert response.status_code == 200
assert b"Cyclic queries are forbidden" in response.content
Expand All @@ -312,7 +312,7 @@ def test_locale_localizations_cyclic(client):
}"""
}

response = client.get("/graphql", body, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", body, HTTP_ACCEPT="application/json")

assert response.status_code == 200
assert b"Cyclic queries are forbidden" in response.content
16 changes: 8 additions & 8 deletions pontoon/api/tests/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ def projects_query():
def test_graphql_dev_get(settings, projects_query, client):
settings.DEV = True

response = client.get("/graphql", projects_query, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", projects_query, HTTP_ACCEPT="application/json")
assert response.status_code == 200


@pytest.mark.django_db
def test_graphql_dev_post(settings, projects_query, client):
settings.DEV = True

response = client.post("/graphql", projects_query, HTTP_ACCEPT="application/json")
response = client.post("/graphql/", projects_query, HTTP_ACCEPT="application/json")
assert response.status_code == 200


Expand All @@ -38,7 +38,7 @@ def test_graphql_dev_post(settings, projects_query, client):
def test_graphql_prod_get(settings, projects_query, client):
settings.DEV = True

response = client.get("/graphql", projects_query, HTTP_ACCEPT="application/json")
response = client.get("/graphql/", projects_query, HTTP_ACCEPT="application/json")
assert response.status_code == 200


Expand All @@ -47,22 +47,22 @@ def test_graphql_prod_get(settings, projects_query, client):
def test_graphql_prod_post(settings, projects_query, client):
settings.DEV = False

response = client.post("/graphql", projects_query, HTTP_ACCEPT="appication/json")
response = client.post("/graphql/", projects_query, HTTP_ACCEPT="application/json")
assert response.status_code == 200


@pytest.mark.django_db
def test_graphiql_dev_get(settings, projects_query, client):
settings.DEV = True

response = client.get("/graphql", projects_query, HTTP_ACCEPT="text/html")
response = client.get("/graphql/", projects_query, HTTP_ACCEPT="text/html")
assert response.status_code == 200


@pytest.mark.django_db
def test_graphiql_dev_post(settings, projects_query, client):
settings.DEV = True
response = client.post("/graphql", projects_query, HTTP_ACCEPT="text/html")
response = client.post("/graphql/", projects_query, HTTP_ACCEPT="text/html")
assert response.status_code == 200


Expand All @@ -71,7 +71,7 @@ def test_graphiql_dev_post(settings, projects_query, client):
def test_graphiql_prod_get(settings, projects_query, client):
settings.DEV = False
reload_urls(settings)
response = client.get("/graphql", projects_query, HTTP_ACCEPT="text/html")
response = client.get("/graphql/", projects_query, HTTP_ACCEPT="text/html")
assert response.status_code == 400


Expand All @@ -80,5 +80,5 @@ def test_graphiql_prod_get(settings, projects_query, client):
def test_graphiql_prod_post(projects_query, client, settings):
settings.DEV = False
reload_urls(settings)
response = client.post("/graphql", projects_query, HTTP_ACCEPT="text/html")
response = client.post("/graphql/", projects_query, HTTP_ACCEPT="text/html")
assert response.status_code == 400
9 changes: 5 additions & 4 deletions pontoon/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from graphene_django.views import GraphQLView

from django.urls import path
from django.urls import re_path

from pontoon.api.schema import schema
from pontoon.settings import DEV


urlpatterns = [
# GraphQL endpoint. In DEV mode it serves the GraphiQL IDE if accessed with Accept: text/html
path(
"graphql",
# GraphQL endpoint. In DEV mode it serves the GraphiQL IDE if accessed with Accept: text/html.
# Explicitly support URLs with or without trailing slash in order to support curl requests.
re_path(
r"^graphql/?$",
GraphQLView.as_view(schema=schema, graphiql=DEV),
),
]

0 comments on commit 6a8744b

Please sign in to comment.