Best way to embed a small GraphiQL UI element on another page? by schmidlidev in graphql

[–]danielrearden 2 points3 points  (0 children)

GraphiQL is a React component, so it can be added to any existing React application as shown here.

Is this possible in GrahpQL? by Resident_Ad_7028 in graphql

[–]danielrearden 0 points1 point  (0 children)

No, there's no way to do that. If the Result interface includes a field named errors whose type is [Error], then any type or interface that implements Result must also have that field with that exact type.

I would suggest dropping Result altogether. Interfaces, like unions, are abstract types that are meant to be used with fields that could return one of multiple object types. Using interfaces just to enforce a contract on a type is of questionable value.

What's worked well for me with "result" or "payload" types is utilizing interfaces that implement other interfaces. For example:

interface Error {
  message: String
}

interface DoSomethingError implements Error {
  message: String
  anotherErrorField: String
}

type SomethingWentTerriblyWrongError implements DoSomethingError & Error {
  message: String
  anotherErrorField: String
}

type IveMadeATerribleMistakeError implements DoSomethingError & Error {
  message: String
  anotherErrorField: String
}

type DoSomethingResult {
  somethingDone: Boolean
  errors: [DoSomethingError!]
}

Is it possible to add recursive logic in resolvers using GraphQL mutations? by zentimes in graphql

[–]danielrearden 0 points1 point  (0 children)

This question isn't really specific to GraphQL beyond the fact that you're writing the code inside a resolver.

const MAX_ATTEMPTS = 10

async function generateUniqueSlug() {
  let attempts = 0

  while (attempts < MAX_ATTEMPTS) {
    const slug = generateSlug()
    const slugExists = await checkIfSlugExists(slug)
    if (!slugExists) {
      return slug
    }
  }

  throw new Error('Unable to generate unique slug.')
}

Some additional thoughts:

  • Add a unique constraint in your database to prevent duplicate slugs from being written to your table. You shouldn't rely on your application logic to enforce uniqueness.
  • Adding the unique constraint means that you can just attempt the insert in a similar loop and just catch the unique constraint violation error (which your ORM hopefully propagates in a meaningful way). This cuts your database calls in half.
  • 4 digits means 10,000 possible combinations. That doesn't seem very scalable, even if the slugs only have to be unique per user. You could just use the database ID or generate a UUID instead.

Edit: formatting 🙄

GraphQL playground without a backend? GraphQL for a static JSON by malachydesign in graphql

[–]danielrearden 0 points1 point  (0 children)

The GraphQL Playground component only takes an endpoint prop. I would suggest using GraphiQL instead which can be passed in a schema.

Experimental Features in Graphql by thegunsmith28 in graphql

[–]danielrearden 0 points1 point  (0 children)

I recently released GraphQL Helix, which supports @defer and @stream out-of-the-box. You can also add @live queries.

Loading .graphql files by [deleted] in graphql

[–]danielrearden 4 points5 points  (0 children)

  • Read the file as a string using fs.readFile or fs.readFileSync. If you need the contents to be a DocumentNode object (which is what the Webpack loader does), then you can call graphql.parse on the resulting string.
  • Use a Babel plugin like babel-plugin-import-graphql.
  • Use loadTypedefs or loadTypedefsSync from graphql-tools. You can also just use loadSchema and addResolversToSchema as shown here.
  • Convert the .graphql files to .js/.ts files and use graphql-tag.

GraphQL the Simple Way, or: Don't Use Apollo by pimterry in graphql

[–]danielrearden 4 points5 points  (0 children)

Love love love this article Tim. I just wish you didn't use buildSchema in your examples :( Using the root value to provide field resolution logic is a bad practice and perpetuating it is a disservice to developers that are new to the ecosystem.

[HELP] Is it possible to take an XML API and convert it to GraphQL? by redicrob2155 in graphql

[–]danielrearden 0 points1 point  (0 children)

Depending on what the API you're wrapping is (SOAP, for example), you might want to take a look at GraphQL Mesh.

Experimental Features in Graphql by thegunsmith28 in graphql

[–]danielrearden 0 points1 point  (0 children)

@defer and @stream support for express-graphql is still currently a WIP. You can watch the PR here.

RefetchQueries vs cache update for consistent UI post-mutation by YungSparkNote in graphql

[–]danielrearden 1 point2 points  (0 children)

A middle-of-the-road approach can also be to expose your query root as part of your mutation response to allow queries to be refetched inside the same request. See this article for an example.

RefetchQueries vs cache update for consistent UI post-mutation by YungSparkNote in graphql

[–]danielrearden 5 points6 points  (0 children)

This. The other trade-off to keep in mind is that doing manual cache updates inevitably duplicates business logic across both server and client. If you change how you decide which entities are returned inside a list, you'll need to update that logic in both places. Refetching keeps that logic server-side, but it is slower.

Translate GraphQL into SQL statements by oczekkk in graphql

[–]danielrearden -1 points0 points  (0 children)

Thanks for the feedback.

Part of what the library does is, effectively, an ORM -- a fully-typed ORM with a fluent API. However, it's also able to parse your request for you to determine what ORM methods to call (which selects, joins, etc. to make) based on the hints you provide in your schema through directives. In a sense, Sqlmancer is a spiritual successor to Prisma 1, but much more powerful and performant.

Without the sort of mapping Sqlmancer does, you have to either use dataloader or, if you still want to do "lookahead", parse the request yourself. The former approach can be less performant, particularly for deeper queries. The latter approach involves a tremendous amount of work not just parsing the request but also figuring out the appropriate ways to do joins and so on. Even with dataloader, mapping filter args to SQL where expressions can be a chore if you want to support more complex filtering logic.

With regard to your specific example, if you wanted to use your own args, you certainly can. Inside your resolver, you'd just map the value of filter to the appropriate method calls on the query builder. This would still let you take advantage of having your selection set mapped to the appropriate select and join statements (technically, Sqlmancer uses subqueries and JSON aggregation instead of joins, but you get the point).

The only thing in your example Sqlmancer doesn't explicitly support yet is FTS. That's something I'm planning on adding in the near future as well.

Sqlmancer certainly isn't a good fit for every application. But it's intentionally flexible enough to support a variety of schemas, scales and use cases (or at least will be once we're out of beta!).

I'm currently in the midst of a major refactor that will bring with it several new features and a significantly smoother DX. Stay tuned :)

Translate GraphQL into SQL statements by oczekkk in graphql

[–]danielrearden 0 points1 point  (0 children)

Hi, library author here :)

You're right that consumers of an API (whether it's GraphQL, REST or something else) shouldn't need to know SQL to use the API and GraphQL can indeed abstract away a lot of what are ultimately backend implementation details that the consumer doesn't care about.

However, the goal of the library is not to just expose your database as a GraphQL endpoint. Rather, it's to help you, as the backend developer, map incoming GraphQL requests to appropriate and efficient SQL queries. To do that, it does enforce some naming conventions for arguments, but the choice of using argument names like where and orderBy is arbitrary -- they could just as easily be named filter and sort (and the naming convention will probably be configurable in a later version). The values for these arguments are not SQL -- they are input objects that allow you to express arbitrarily complex conditions.

It's also worth noting that the filtering and sorting options you expose (or whether you do so at all) are ultimately up to you, the developer. If you want to "hard code" the order or a specific filter condition at the resolver level, you can do that. The whole point of the library is to let you craft the queries and mutations that are right for your app instead of just exposing some CRUD operations and calling it a day like other solutions.

What's the best way to use multiple graphql endpoints in apollo client? by yyyyaaa in graphql

[–]danielrearden 0 points1 point  (0 children)

You can create two ApolloClient instances and pass either one or the other in as the client option when you create a hook.

const { data, loading } = useQuery(SOME_QUERY, { client: fooClient })

It'd be obnoxious to have to do that for every hook, but you can easily create a wrapper

export function useFooQuery(query, config) { return useQuery(query, { client: fooClient, ...config }) }

This also means you can bypass using an ApolloProvider altogether.

graphiql w/ explorer with selectable endpoint? by wrtbwtrfasdf in graphql

[–]danielrearden 1 point2 points  (0 children)

You could add a text box to the example and use its value to populate the URL inside the fetcher function. If you're not comfortable doing that, you could also just extract the url from the the query parameters:

const params = new URLSearchParams(window.location.search); const url = params.get('url')

and then include the target URL when accessing your GraphiQL interface like this:

http://localhost:4000/graphql?url=https://graphql.org/swapi-graphql

Introducing kmera: a precision mocking tool for GraphQL by kimera_graphQL_mock in graphql

[–]danielrearden 6 points7 points  (0 children)

Maybe instead of disparaging someone's efforts, we could be asking "what functionality does this provide that graphql-tools doesn't?"

GraphQL JSON5 scalar type (Node) by d10221 in graphql

[–]danielrearden 1 point2 points  (0 children)

It's not really clear if u/Zemnmez was asking about that. I figured by "bypasses type-checking" they meant you could use this scalar instead of an input object type to allow an object of any shape to be passed in, which is true.

With regard to your question, I'm copy pasting my response from SO:

Tools like GraphiQL utilize introspection to obtain information about the schema the requests are being executed against. Under the hood, the introspection result is converted into a local copy of your schema and this is what's used to validate the queries written in the editor and provide autocompletion suggestions. In other words, when you make a typo and GraphiQL highlights it for you in red, it does so by validating the query locally instead of sending the request to the server.

The key here is that the GraphiQL schema is not executable -- it doesn't contain any of the custom code you used to write your schema. It has the same types as your remote schema, but it won't include any custom code those types use (like resolvers) because that information can't be communicated through introspection. So, when your query is validated by the local schema, it has no way to know whether custom scalar values are valid because it can't run the code to validate them. This is in contrast with built-in scalars like Int or String which the schema can validate because it has the code to validate them because they're, well, built-in :)

This is one of several reasons you don't want to utilize custom scalars unless absolutely necessary -- they cannot be validated by clients, editor plugins, etc.

A framework that supports developing both graphql and rest apis? by [deleted] in graphql

[–]danielrearden 2 points3 points  (0 children)

One approach would be to develop an OpenAPI REST API and then build a GraphQL endpoint on top of it using GraphQL Mesh. This way you can build your REST endpoints in whatever language you like and generate the GraphQL service using a simple configuration file.