0.0.31 • Published 3 years ago
@magiql/ide v0.0.31
Important: Very early project and under active development, would love any feedback or help
Install
npm install @magiql/ide
// or
yarn add @magiql/ide
Features
- Goal: IDE-like experience for GraphQL exploration and development (eg. CodeSandbox for frontend) using
monaco-editor
- Language service: supported using web workers (everything is off the main UI thread)
Uses
graphql-language-service
Based on work onmonaco-graphql
Syntax highlighting Schema-aware auto-completions Validations and error highlighting Formatting on Cmd + S (using prettier) * Run queries, mutations, and subscriptions (in development) - Explorer: point-and-click UI to manipulate the AST with hints from the schema (in development):
Completely inspired by
OneGraph/graphiql-explorer
Goal: represent the entire AST as an explorer with hints from the schema Looks exactly like GraphQL syntax (syntax highlighted), but only the customizable parts should need user input, everything else should be toggles or buttons Would allow very easy exploration of API for non technical users as well, could hide text editor also Implementation: uses codegen to generate arecoil
based AST data structure using the types in thegraphql
package, the Explorer is also just a renderer of the AST, that can update any part of the AST by updating its atom, and a new AST will be build The AST is exported as collection of recoil atoms: can be modified externally by other plugins - User interface: Goal: Browser-like UI for exploring GraphQL APIs Edit the URL in the nav bar to connect to any GraphQL API Support for multiple tabs: each has own schema configuration (url, headers), query, variables, etc. Resizable and configurable panels for everything (query, explorer, variables, headers, settings, etc.): extendable to allow plugins to add panels and switch to them * Persists configuration, history, etc to localStorage to get a stateful user experience
- Embeddable: Exports components that can be used in any React App,
Loads
monaco-editor
and web workers from CDNs to avoid any extra bundling step to include them CSS is added at runtime bybeamwind
so that its not necessary to bundle css - Extendable:
IDE state exported as collection of Recoil atoms for plugins to manipulate them and react to them as necessary
Plugin API to provide custom panels and functionality,
Can run expensive stuff on web workers and
use-monaco
gives a really easy API to register and use workers that use text files frommonaco-editor
Ideas for plugins: GraphQL faker: design schema in one panels and explore it in another Hasura: create panel to generate declarative metadata/migrations like tables, etc Response manipulation: Allow user to write custom code in a panel that can be run with the result of the response, (like lodash, etc or persisting) Could create CLI / plugin to read directory and get GraphQL documents and have them available for exploration @magiql/ide/render
can be used by GraphQL servers as an alternative to GraphQL playground (usage shown below) * Should be configurable with plugins and initial state of IDE- Tech used:
react
recoil
: state management toolbeamwind
: a collection of packages to compile Tailwind CSS like shorthand syntax into CSS at runtimeuse-monaco
: wrapper aroundmonaco-editor
, handles loading from CDN and managing workers, exposes easier APIs to extend the editor
Usage for GraphQL server
import {
getGraphQLParameters,
processRequest,
shouldRenderGraphiQL,
} from "graphql-helix";
import { renderPlayground } from "@magiql/ide/render";
const allowCors = (fn) => async (req, res) => {
// ... middleware to allow cors for development
return await fn(req, res);
};
export default allowCors(async (req, res) => {
const request = {
body: req.body,
headers: req.headers,
method: req.method,
query: req.query,
};
if (shouldRenderGraphiQL(request)) {
res.send(
/*
* returns HTML that you send from a server
*/
renderPlayground({
uri: "/api/graphql",
})
);
} else {
const { operationName, query, variables } = getGraphQLParameters(request);
const result = await processRequest({
operationName,
query,
variables,
request,
schema,
});
if (result.type === "RESPONSE") {
result.headers.forEach(({ name, value }) => res.setHeader(name, value));
res.status(result.status);
res.json(result.payload);
}
}
});
Usage in React App
import GraphQLIDE from "@magiql/ide";
export default function App() {
return (
<GraphQLIDE
schemaConfig={{
// whichever GraphQL endpoint you want to connect to,
// to access Next JS API Routes, we need the full url
uri: window.location.origin + "/api/graphql",
}}
/>
)
}
Usage in server-rendered React App
As the tool is web-based, in case your app is server-rendered, use the following to skip rendering the IDE on the server
import GraphQLIDE from "@magiql/ide";
export default function App() {
return typeof window !== "undefined" ? (
<GraphQLIDE
schemaConfig={{
uri: window.location.origin + "/api/graphql",
}}
/>
) : (
<></>
);
}
0.0.31
3 years ago
0.0.30
3 years ago
0.0.29
3 years ago
0.0.27
3 years ago
0.0.26
3 years ago
0.0.25
3 years ago
0.0.24
3 years ago
0.0.22
3 years ago
0.0.23
3 years ago
0.0.21
3 years ago
0.0.20
3 years ago
0.0.14
3 years ago
0.0.15
3 years ago
0.0.16
3 years ago
0.0.17
3 years ago
0.0.18
3 years ago
0.0.19
3 years ago
0.0.13
3 years ago
0.0.12
3 years ago
0.0.10
3 years ago
0.0.11
3 years ago
0.0.9
3 years ago
0.0.8
3 years ago
0.0.7
3 years ago
0.0.3
3 years ago
0.0.5
3 years ago
0.0.4
3 years ago
0.0.6
3 years ago
0.0.2
3 years ago
0.0.1
3 years ago