feat(graphql): Remove GraphQL Explorer embed (#58109)
Co-authored-by: Christophe (Xtof) Dehaudt <xtof.dehaudt@gmail.com> Co-authored-by: Christophe (Xtof) Dehaudt <xtofx@github.com>
This commit is contained in:
@@ -112,9 +112,6 @@ For a real-world example, see [Example mutation](#example-mutation).
|
|||||||
|
|
||||||
[Variables](https://graphql.org/learn/queries/#variables) can make queries more dynamic and powerful, and they can reduce complexity when passing mutation input objects.
|
[Variables](https://graphql.org/learn/queries/#variables) can make queries more dynamic and powerful, and they can reduce complexity when passing mutation input objects.
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> If you're using the Explorer, make sure to enter variables in the separate [Query Variables pane](/graphql/guides/using-the-explorer#using-the-variable-pane), and do not include the word `variables` before the JSON object.
|
|
||||||
|
|
||||||
Here's an example query with a single variable:
|
Here's an example query with a single variable:
|
||||||
|
|
||||||
```graphql
|
```graphql
|
||||||
@@ -269,9 +266,6 @@ mutation AddReactionToIssue {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> Although you can include a query and a mutation in the same Explorer window if you give them names (`FindIssueID` and `AddReactionToIssue` in this example), the operations will be executed as separate calls to the GraphQL endpoint. It's not possible to perform a query at the same time as a mutation, or vice versa.
|
|
||||||
|
|
||||||
Let's walk through the example. The task sounds simple: add an emoji reaction to an issue.
|
Let's walk through the example. The task sounds simple: add an emoji reaction to an issue.
|
||||||
|
|
||||||
So how do we know to begin with a query? We don't, yet.
|
So how do we know to begin with a query? We don't, yet.
|
||||||
@@ -294,7 +288,7 @@ Let's examine the query line by line:
|
|||||||
|
|
||||||
* `query FindIssueID {`
|
* `query FindIssueID {`
|
||||||
|
|
||||||
Here we're performing a query, and we name it `FindIssueID`. Note that naming a query is optional; we give it a name here so that we can include it in same Explorer window as the mutation.
|
Here we're performing a query, and we name it `FindIssueID`. Note that naming a query is optional; we give it a name here so that we can include it in same GUI client window as the mutation.
|
||||||
|
|
||||||
* `repository(owner:"octocat", name:"Hello-World") {`
|
* `repository(owner:"octocat", name:"Hello-World") {`
|
||||||
|
|
||||||
@@ -317,7 +311,7 @@ With the ID known, we can proceed with the mutation:
|
|||||||
|
|
||||||
* `mutation AddReactionToIssue {`
|
* `mutation AddReactionToIssue {`
|
||||||
|
|
||||||
Here we're performing a mutation, and we name it `AddReactionToIssue`. As with queries, naming a mutation is optional; we give it a name here so we can include it in the same Explorer window as the query.
|
Here we're performing a mutation, and we name it `AddReactionToIssue`. As with queries, naming a mutation is optional; we give it a name here so we can include it in the same GUI client window as the query.
|
||||||
|
|
||||||
* `addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {`
|
* `addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {`
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ intro: 'You can run queries on real {% data variables.product.prodname_dotcom %}
|
|||||||
redirect_from:
|
redirect_from:
|
||||||
- /v4/guides/using-the-explorer
|
- /v4/guides/using-the-explorer
|
||||||
- /graphql/guides/using-the-explorer
|
- /graphql/guides/using-the-explorer
|
||||||
|
- /graphql/overview/explorer
|
||||||
versions:
|
versions:
|
||||||
fpt: '*'
|
fpt: '*'
|
||||||
ghec: '*'
|
ghec: '*'
|
||||||
@@ -12,6 +13,10 @@ topics:
|
|||||||
- API
|
- API
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> The GraphQL Explorer was removed from the documentation on November 11, 2025. See our [changelog announcement](https://github.blog/changelog/2025-11-07-graphql-explorer-removal-from-api-documentation-on-november-7-2025).
|
||||||
|
|
||||||
## Using GraphQL client IDEs
|
## Using GraphQL client IDEs
|
||||||
|
|
||||||
There are many open-source GraphQL client IDEs you can use to access {% data variables.product.company_short %}'s GraphQL API.
|
There are many open-source GraphQL client IDEs you can use to access {% data variables.product.company_short %}'s GraphQL API.
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ featuredLinks:
|
|||||||
- /graphql/guides/introduction-to-graphql
|
- /graphql/guides/introduction-to-graphql
|
||||||
- /graphql/guides/using-graphql-clients
|
- /graphql/guides/using-graphql-clients
|
||||||
popular:
|
popular:
|
||||||
- /graphql/overview/explorer
|
|
||||||
- /graphql/overview/public-schema
|
- /graphql/overview/public-schema
|
||||||
- /graphql/guides/using-pagination-in-the-graphql-api
|
- /graphql/guides/using-pagination-in-the-graphql-api
|
||||||
guideCards:
|
guideCards:
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ The docs in the sidebar are generated from the {% data variables.product.prodnam
|
|||||||
|
|
||||||
* Schema-defined types: [scalars](/graphql/reference/scalars), [objects](/graphql/reference/objects), [enums](/graphql/reference/enums), [interfaces](/graphql/reference/interfaces), [unions](/graphql/reference/unions), and [input objects](/graphql/reference/input-objects).
|
* Schema-defined types: [scalars](/graphql/reference/scalars), [objects](/graphql/reference/objects), [enums](/graphql/reference/enums), [interfaces](/graphql/reference/interfaces), [unions](/graphql/reference/unions), and [input objects](/graphql/reference/input-objects).
|
||||||
|
|
||||||
You can access this same content via the [Explorer Docs sidebar](/graphql/guides/using-the-explorer#accessing-the-sidebar-docs). Note that you may need to rely on both the docs and the schema validation to successfully call the GraphQL API.
|
|
||||||
|
|
||||||
For other information, such as authentication and rate limit details, check out the [guides](/graphql/guides).
|
For other information, such as authentication and rate limit details, check out the [guides](/graphql/guides).
|
||||||
|
|
||||||
## Requesting support
|
## Requesting support
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
title: Explorer
|
|
||||||
redirect_from:
|
|
||||||
- /v4/explorer
|
|
||||||
- /v4/explorer-new
|
|
||||||
versions:
|
|
||||||
fpt: '*'
|
|
||||||
ghec: '*'
|
|
||||||
ghes: '*'
|
|
||||||
layout: graphql-explorer
|
|
||||||
topics:
|
|
||||||
- API
|
|
||||||
autogenerated: graphql
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- expires 2025-11-01 -->
|
|
||||||
<!-- We should change this to a note describing what's happened once the date is reached. -->
|
|
||||||
|
|
||||||
> [!WARNING]
|
|
||||||
> The GraphQL Explorer as an embedded tool will be removed from the documentation on November 1, 2025. See our [changelog announcement](https://github.blog/changelog/2025-08-22-graphql-explorer-removal-from-api-documentation-on-november-1-2025).
|
|
||||||
|
|
||||||
For more information about how to explore {% data variables.product.prodname_dotcom %} GraphQL Schema, see [AUTOTITLE](/graphql/guides/using-graphql-clients).
|
|
||||||
|
|
||||||
<!-- end expires 2025-11-01 -->
|
|
||||||
|
|
||||||
{% ifversion ghec %}
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> If your {% data variables.product.prodname_ghe_cloud %} organization uses {% data variables.product.prodname_dotcom %}'s IP allow list, you won't be able to use the GraphQL Explorer. Instead, we recommend using an alternative GraphQL client IDE.
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- Content after this section is automatically generated -->
|
|
||||||
<!-- See pages/[versionId]/graphql/overview/explorer.tsx -->
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Overview
|
title: Overview
|
||||||
intro: 'Learn about the {% data variables.product.prodname_dotcom %} GraphQL API, previews for upcoming changes, breaking changes, and limitations. You can also use the GraphQL Explorer to interact with the API on real {% data variables.product.prodname_dotcom %} data.'
|
intro: 'Learn about the {% data variables.product.prodname_dotcom %} GraphQL API, previews for upcoming changes, breaking changes, and limitations.'
|
||||||
versions:
|
versions:
|
||||||
fpt: '*'
|
fpt: '*'
|
||||||
ghec: '*'
|
ghec: '*'
|
||||||
@@ -10,7 +10,6 @@ children:
|
|||||||
- /public-schema
|
- /public-schema
|
||||||
- /breaking-changes
|
- /breaking-changes
|
||||||
- /changelog
|
- /changelog
|
||||||
- /explorer
|
|
||||||
- /rate-limits-and-query-limits-for-the-graphql-api
|
- /rate-limits-and-query-limits-for-the-graphql-api
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ curl -X POST -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application
|
|||||||
|
|
||||||
For more information on using the GraphQL API, see:
|
For more information on using the GraphQL API, see:
|
||||||
* [AUTOTITLE](/graphql/guides)
|
* [AUTOTITLE](/graphql/guides)
|
||||||
* [AUTOTITLE](/graphql/overview/explorer)
|
|
||||||
|
|
||||||
### Re-provisioning SCIM for users through your identity provider
|
### Re-provisioning SCIM for users through your identity provider
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
.explorerIframe {
|
|
||||||
height: 45rem;
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
import { GetServerSideProps } from 'next'
|
|
||||||
|
|
||||||
import { MainContextT, MainContext, getMainContext } from '@/frame/components/context/MainContext'
|
|
||||||
import { AutomatedPage } from '@/automated-pipelines/components/AutomatedPage'
|
|
||||||
import {
|
|
||||||
AutomatedPageContext,
|
|
||||||
AutomatedPageContextT,
|
|
||||||
getAutomatedPageContextFromRequest,
|
|
||||||
} from '@/automated-pipelines/components/AutomatedPageContext'
|
|
||||||
import { useEffect, useRef } from 'react'
|
|
||||||
|
|
||||||
import styles from './explorer.module.scss'
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
mainContext: MainContextT
|
|
||||||
graphqlExplorerUrl: string
|
|
||||||
automatedPageContext: AutomatedPageContextT
|
|
||||||
}
|
|
||||||
export default function GQLExplorer({
|
|
||||||
mainContext,
|
|
||||||
graphqlExplorerUrl,
|
|
||||||
automatedPageContext,
|
|
||||||
}: Props) {
|
|
||||||
const graphiqlRef = useRef<HTMLIFrameElement>(null)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof window !== 'undefined' && window.location.search) {
|
|
||||||
graphiqlRef.current?.contentWindow?.postMessage(window.location.search, graphqlExplorerUrl)
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MainContext.Provider value={mainContext}>
|
|
||||||
<AutomatedPageContext.Provider value={automatedPageContext}>
|
|
||||||
<AutomatedPage fullWidth={true}>
|
|
||||||
<div>
|
|
||||||
<iframe
|
|
||||||
ref={graphiqlRef}
|
|
||||||
className={`border width-full ${styles.explorerIframe}`}
|
|
||||||
scrolling="no"
|
|
||||||
src={graphqlExplorerUrl}
|
|
||||||
title="GitHub GraphQL API"
|
|
||||||
>
|
|
||||||
You must have iframes enabled to use this feature.
|
|
||||||
</iframe>
|
|
||||||
</div>
|
|
||||||
</AutomatedPage>
|
|
||||||
</AutomatedPageContext.Provider>
|
|
||||||
</MainContext.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
|
||||||
const req = context.req as any
|
|
||||||
const res = context.res as any
|
|
||||||
const graphqlExplorerUrl =
|
|
||||||
process.env.NODE_ENV === 'production'
|
|
||||||
? 'https://graphql.github.com/explorer'
|
|
||||||
: 'http://localhost:3000'
|
|
||||||
const automatedPageContext = getAutomatedPageContextFromRequest(req)
|
|
||||||
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
mainContext: await getMainContext(req, res),
|
|
||||||
graphqlExplorerUrl,
|
|
||||||
automatedPageContext,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default, getServerSideProps } from '@/graphql/pages/explorer'
|
|
||||||
@@ -47,12 +47,9 @@ export default function handleRedirects(req: ExtendedRequest, res: Response, nex
|
|||||||
// The `q` param is deprecated, but we still need to support it in case
|
// The `q` param is deprecated, but we still need to support it in case
|
||||||
// there are links out there that use it.
|
// there are links out there that use it.
|
||||||
const onSearch = req.path.endsWith('/search') || req.path.startsWith('/api/search')
|
const onSearch = req.path.endsWith('/search') || req.path.startsWith('/api/search')
|
||||||
// We have legacy links that links to the GraphQL Explorer with
|
|
||||||
// a `?query=...` in the URL. These should not redirect to the search page.
|
|
||||||
const onGraphqlExplorer = req.path.includes('/graphql/overview/explorer')
|
|
||||||
const hasQ = 'q' in req.query
|
const hasQ = 'q' in req.query
|
||||||
const hasQuery = 'query' in req.query
|
const hasQuery = 'query' in req.query
|
||||||
if ((hasQ && !hasQuery) || (hasQuery && !onSearch && !onGraphqlExplorer)) {
|
if ((hasQ && !hasQuery) || (hasQuery && !onSearch)) {
|
||||||
const language = getLanguage(req)
|
const language = getLanguage(req)
|
||||||
const sp = new URLSearchParams(req.query as URLSearchParamsTypes)
|
const sp = new URLSearchParams(req.query as URLSearchParamsTypes)
|
||||||
if (sp.has('q') && !sp.has('query')) {
|
if (sp.has('q') && !sp.has('query')) {
|
||||||
|
|||||||
@@ -82,11 +82,6 @@ describe('redirects', () => {
|
|||||||
const res = await get(reqPath)
|
const res = await get(reqPath)
|
||||||
expect(res.statusCode).toBe(200)
|
expect(res.statusCode).toBe(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Do not redirect to search if on GraphQL Explorer "search"', async () => {
|
|
||||||
const res = await get('/en/graphql/overview/explorer?query=anything')
|
|
||||||
expect(res.statusCode).toBe(200)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('trailing slashes', () => {
|
describe('trailing slashes', () => {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ describe('developer.github.com redirects', () => {
|
|||||||
'/webhooks',
|
'/webhooks',
|
||||||
'/v3/guides/managing-deploy-keys',
|
'/v3/guides/managing-deploy-keys',
|
||||||
'/apps/building-oauth-apps/authorizing-oauth-apps',
|
'/apps/building-oauth-apps/authorizing-oauth-apps',
|
||||||
'/v4/explorer',
|
|
||||||
'/v3/search',
|
'/v3/search',
|
||||||
'/apps',
|
'/apps',
|
||||||
'/v3/activity/events/types',
|
'/v3/activity/events/types',
|
||||||
|
|||||||
@@ -65,8 +65,7 @@ export default function parsePageSectionsIntoRecords(page: any): Record {
|
|||||||
|
|
||||||
let body = ''
|
let body = ''
|
||||||
// Typical example pages with no `$root` are:
|
// Typical example pages with no `$root` are:
|
||||||
// https://docs.github.com/en/code-security/guides or
|
// https://docs.github.com/en/code-security/guides
|
||||||
// https://docs.github.com/en/graphql/overview/explorer
|
|
||||||
//
|
//
|
||||||
// We need to avoid these because if you use `getAllText()` on these
|
// We need to avoid these because if you use `getAllText()` on these
|
||||||
// pages, it will extract *everything* from the page, which will
|
// pages, it will extract *everything* from the page, which will
|
||||||
|
|||||||
Reference in New Issue
Block a user