GithubHelp home page GithubHelp logo

graphql-binding / graphql-static-binding Goto Github PK

View Code? Open in Web Editor NEW
24.0 24.0 7.0 168 KB

Generate static binding files for a GraphQL schema

License: MIT License

TypeScript 98.51% JavaScript 0.76% Gherkin 0.73%

graphql-static-binding's Introduction

graphql-binding

Deprecation Notice!

In the last few months, since the transition of many libraries under The Guild's leadership, We've reviewed and released many improvements and versions to graphql-cli, graphql-config and graphql-import.

We've reviewed graphql-binding, had many meetings with current users and engaged the community also through the roadmap issue.

What we've found is that the new GraphQL Mesh library is covering not only all the current capabilities of GraphQL Binding, but also the future ideas that were introduced in the original GraphQL Binding blog post and haven't come to life yet.

And the best thing - GraphQL Mesh gives you all those capabilities, even if your source is not a GraphQL service at all!
it can be GraphQL, OpenAPI/Swagger, gRPC, SQL or any other source! And of course you can even merge all those sources into a single SDK.

Just like GraphQL Binding, you get a fully typed SDK (thanks to the protocols SDKs and the GraphQL Code Generator), but from any source, and that SDK can run anywhere, as a connector or as a full blown gateway. And you can share your own "Mesh Modules" (which you would probably call "your own binding") and our community already created many of those! Also, we decided to simply expose regular GraphQL, so you can choose how to consume it using all the awesome fluent client SDKs out there.

If you think that we've missed anything from GraphQL Binding that is not supported in a better way in GraphQL Mesh, please let us know!

Overview

๐Ÿ”— GraphQL bindings are modular building blocks that allow to embed existing GraphQL APIs into your own GraphQL server. Think about it as turning (parts of) GraphQL APIs into reusable LEGO building blocks. Bindings may be generated in JavaScript, TypeScript, or Flow.

The idea of GraphQL bindings is introduced in detail in this blog post: Reusing & Composing GraphQL APIs with GraphQL Bindings

Install

yarn add graphql-binding

Public GraphQL bindings

You can find practical, production-ready examples here:

Note: If you've created your own GraphQL binding based on this package, please add it to this list via a PR ๐Ÿ™Œ

If you have any questions, share some ideas or just want to chat about GraphQL bindings, join the #graphql-bindings channel in our Slack.

graphql-static-binding's People

Contributors

kbrandwijk avatar ojkelly avatar renovate-bot avatar renovate[bot] avatar schickling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

graphql-static-binding's Issues

Support the special single element version of lists

GraphQL support single element lists to be written as if they were an object. Ie, these are equivalent:

data: { progress: { create: [{ message }] } }
data: { progress: { create: { message } } }

It would be great if the generated binding could support this as well

For optional fields, there is no constraint of type "null"

Bug Report

Current behavior

There is no possibility of setting the value "null" for arguments because of the restrictions on types

Reproduction

Scheme

type User {
  id: ID! @unique
  name: String!
}

type Post {
  id: ID! @unique
  isPublished: Boolean! @default(value: "false")
  title: String!
  text: String # Not required
  user: User # Not required
}

./generated/prisma.ts

// ...
export interface PostWhereInput {
  AND?: PostWhereInput[] | PostWhereInput
  OR?: PostWhereInput[] | PostWhereInput
  id?: ID_Input
  id_not?: ID_Input
  id_in?: ID_Input[] | ID_Input
  id_not_in?: ID_Input[] | ID_Input
  id_lt?: ID_Input
  id_lte?: ID_Input
  id_gt?: ID_Input
  id_gte?: ID_Input
  id_contains?: ID_Input
  id_not_contains?: ID_Input
  id_starts_with?: ID_Input
  id_not_starts_with?: ID_Input
  id_ends_with?: ID_Input
  id_not_ends_with?: ID_Input
  isPublished?: Boolean
  isPublished_not?: Boolean
  title?: String
  title_not?: String
  title_in?: String[] | String
  title_not_in?: String[] | String
  title_lt?: String
  title_lte?: String
  title_gt?: String
  title_gte?: String
  title_contains?: String
  title_not_contains?: String
  title_starts_with?: String
  title_not_starts_with?: String
  title_ends_with?: String
  title_not_ends_with?: String
  text?: String // Must be: Nullable<String> where: type Nullable<T> = T | null
  text_not?: String // Must be: Nullable<String> where: type Nullable<T> = T | null
  text_in?: String[] | String
  text_not_in?: String[] | String
  text_lt?: String
  text_lte?: String
  text_gt?: String
  text_gte?: String
  text_contains?: String
  text_not_contains?: String
  text_starts_with?: String
  text_not_starts_with?: String
  text_ends_with?: String
  text_not_ends_with?: String
  user?: UserWhereInput // Must be: Nullable<UserWhereInput> where: type Nullable<T> = T | null
}
// ...
export type Query = {
// ...
posts: (args: { where?: PostWhereInput, orderBy?: PostOrderByInput, skip?: Int, after?: String, before?: String, first?: Int, last?: Int }, info?: GraphQLResolveInfo | string) => Promise<Post[]>
// ...
}

Resolver usage

myResolver(parent, args, context, info) {
  return context.db.query.posts(
    { 
      where: {
        isPublished: true,
        user: null // Error: The type "null" can not be assigned for the type "UserWhereInput | undefined".
      }
    },
      info
  );
}

Expected behavior?

No typescript validation errors.

Typescript --strictFunctionTypes parameter incompatibility

Edit: This only happens with strictFunctionTypes. Seems like it would be good to support that

Using binding-ts, I'm getting some errors in the generated ts file:

generated/starchive-api.ts(28,3): error TS2416: Property 'query' in type 'Binding' is not assignable to the same property in base type 'Binding<QueryMap, SubscriptionMap>'.
  Type 'Query' is not assignable to type 'QueryMap'.
    Property 'helloWorld' is incompatible with index signature.
      Type '(args: {}, context: { [key: string]: any; }, info?: string | GraphQLResolveInfo | undefined) => P...' is not assignable to type '(args?: { [key: string]: any; } | undefined, context?: { [key: string]: any; } | undefined, info?...'.
        Types of parameters 'args' and 'args' are incompatible.
          Type '{ [key: string]: any; } | undefined' is not assignable to type '{}'.
            Type 'undefined' is not assignable to type '{}'.

Am I missing something? All the parameters in QueryMap are optional so shouldn't the generated

export type Query = {
  helloWorld: (args: {}, context: { [key: string]: any }, info?: GraphQLResolveInfo | string) => Promise<String | null>
}

actually be this?

export type Query = {
  helloWorld: (args?: {}, context?: { [key: string]: any }, info?: GraphQLResolveInfo | string) => Promise<String | null>
}

However, making that change causes another issue because Binding#delegate doesn't have optional parameters either

Change dependency tree structure

The current dependency tree looks similar to this:

     +-------------+
     |             |
     | graphql-cli |
     |             |
     +------+------+
            ^
            |
 +----------+----------+
 |                     |
 | graphql-cli-prepare |
 |                     |
 +----------+----------+
            ^
            |
+-----------+------------+
|                        |
| graphql-binding-static |
|                        |
+------------------------+

This means for every change that's introduced in graphql-binding-static a new version of graphql-cli-prepare and graphql-cli needs to be released and installed in order to use the latest graphql-binding-static changes.

I'd like to change the dependency hierarchy in a way to "colocate" dynamic and static bindings (e.g. put prisma-binding next to the static binding generator for prisma).

Thoughts and idea on this are highly appreciated. ๐ŸŽ‰

(Optionally) include typeDefs in generated .ts (.js) file

I'd like to use my own bindings in the browser, but the typeDefs aren't available (fs.readFile). A solution is to import the typeDefs separately (fetch in the browser). But I'd prefer to have the typedefs available in the generated .ts file, like Prisma does.

Could this be included in the default generator? (binding-ts) .

(Or maybe have this available as option for the default generator)

Using binding-ts for defining resolvers

I am not entirely sure what is the use case for binding-ts generator. I assume it's not meant to add type safety to resolvers? Either way, if I would like to make another generator for this case, would you accept PR for it or should it go as a standalone module? Unfortunately, it would be a lot of copy & paste.


Let me explain what issues there are for that generator to be used for resolvers properly. Besides regular types, enums, inputs ... which are correctly generated, there is this type.

export type Mutation = {
  authPlayer: (args: { input?: AuthPlayerInput }, context: { [key: string]: any }, info?: GraphQLResolveInfo | string) => Promise<AuthPlayer>
}

I cannot figure out how I would use that for typing my resolver. Also, there is an issue of a missing first argument being parent object.

Instead, I've figured out that this approach might serve much better.

export namespace Mutation {
  export authPlayer: (parent: any, args: { input?: AuthPlayerInput }, context: { [key: string]: any }, info?: GraphQLResolveInfo | string) => Promise<AuthPlayer>
}

const authPlayer: Mutation.authPlayer = async (_, { input }, ctx: Context) => {
   // nice type checking even for a return value
}

Looking at the code it shouldn't be that hard to do required tweaks, but it will be a lot of copy&paste which I am not for fond of :) Opinions?

consider aliasing ID type to string only

Currently the ID type alias to string | number:

/*
The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
*/
export type ID = string | number

This makes sense, but has the unfortunate consequence of making it more difficult to pass the id around internally:

image

I'm not sure this should change, but wanted to bring it up

Class 'Prisma' incorrectly extends base class 'Prisma' with strictFunctionTypes

Bug Report

Current behavior
After trying to compile typescript, I get the following error:

src/generated/prisma.ts(6790,14): error TS2415: Class 'Prisma' incorrectly extends base class 'Prisma'.
  Types of property 'query' are incompatible.
    Type 'Query' is not assignable to type 'QueryMap'.
      Index signature is missing in type 'Query'.

when "strictFunctionTypes": true is used in tsconfig.json.

Reproduction

https://github.com/SpaceK33z/prisma-typescript-error

Expected behavior?

"strictFunctionTypes": true is supported


Thanks to @iamclaytonray, @SpaceK33z, @kbrandwijk for their input in the initially reported issue.

Add TSLint:Disable to generated/graphcool.ts

From @philcockfield on January 8, 2018 17:48

With GraphCool 1.0 a TypeScript file is generated locally after deploy:

/src/generated/graphcool.ts

This produces typescript that may conflict with the projects tslint.json rules.
Can you include a

// tslint:disable

directive at the top of the generated file to exclude it from the projects linting output, please?

Thanks.

Copied from original issue: prisma/prisma1#1543

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.