tailcall icon indicating copy to clipboard operation
tailcall copied to clipboard

Support multiple upstream settings

Open meskill opened this issue 1 year ago • 5 comments

Is your feature request related to a problem? Please describe.

@upstream directive is used to define some settings for the upstream server that will affect all of the requests made by tailcall. Currently, it's only possible to define one upstream setup that will be shared by all of the resolvers. Current approach, doesn't allow to specify different settings for different upstream and the limits setup ability for cases of tailcall to multiple non-equivalent apis.

Describe the solution you'd like

Able to specify multiple @upstream directives for different apis that could be referenced by id for resolvers.

Or rethink the way the upstream settings are defined.

Describe alternatives you've considered

We can put all of the required settings to the resolver level, but it will require a lot of duplication in logic for multiple resolver operators and also duplication for settings for resolvers to the same upstream from different fields.

meskill avatar Dec 08 '23 10:12 meskill

@meskill Proposed solution, let me know your thoughts.

  1. If only a single upstream is specified, it will be the default, and things will work as before.
schema
  @server(port: 8000, graphiql: true, hostname: "0.0.0.0")
  @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: true) {
  query: Query
}

type Query {
  # gets posts from http://jsonplaceholder.typicode.com
  posts: [Post] @http(path: "/posts")

  # gets a user from http://jsonplaceholder.typicode.com
  user(id: Int!): User @http(path: "/users/{{args.id}}")
}
  1. Multiple upstream directives can be specified with different ids.
    http and graphql directives will have an upstream attribute to specify the particular upstream id to get properties from.
    An upstream directive without an id is considered the default, and http and graphql directives that do not specify an upstream attribute will get properties from the default.
    There should be validation to check that there is only one upstream without an id

schema
  @server(port: 8000, graphiql: true, hostname: "0.0.0.0")
  @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: true) 
  @upstream(id: "myupstream" baseURL: "http://myupstream.com", httpCache: true)  {
  query: Query
}

type Query {
  # gets posts from http://jsonplaceholder.typicode.com
  posts: [Post] @http(path: "/posts") 

  # gets a user from http://myupstream.com
  user(id: Int!): User @http(upstream: "myupstream", path: "/users/{{args.id}}")
}
  1. To keep things simple, upstreams will get default values for properties that are not specified, they do not inherit anything from the default upstream.

sujeetsr avatar Dec 12 '23 05:12 sujeetsr

@meskill Proposed solution, let me know your thoughts.

  1. If only a single upstream is specified, it will be the default, and things will work as before.
schema
  @server(port: 8000, graphiql: true, hostname: "0.0.0.0")
  @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: true) {
  query: Query
}

type Query {
  # gets posts from http://jsonplaceholder.typicode.com
  posts: [Post] @http(path: "/posts")

  # gets a user from http://jsonplaceholder.typicode.com
  user(id: Int!): User @http(path: "/users/{{args.id}}")
}
  1. Multiple upstream directives can be specified with different ids. http and graphql directives will have an upstream attribute to specify the particular upstream id to get properties from. An upstream directive without an id is considered the default, and http and graphql directives that do not specify an upstream attribute will get properties from the default. There should be validation to check that there is only one upstream without an id
schema
  @server(port: 8000, graphiql: true, hostname: "0.0.0.0")
  @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: true) 
  @upstream(id: "myupstream" baseURL: "http://myupstream.com", httpCache: true)  {
  query: Query
}

type Query {
  # gets posts from http://jsonplaceholder.typicode.com
  posts: [Post] @http(path: "/posts") 

  # gets a user from http://myupstream.com
  user(id: Int!): User @http(upstream: "myupstream", path: "/users/{{args.id}}")
}
  1. To keep things simple, upstreams will get default values for properties that are not specified, they do not inherit anything from the default upstream.

Sound good for me. In implementation we should add validation for uniqueness of the id and proper upstream referencing.

meskill avatar Dec 12 '23 10:12 meskill

can't we use leverage enums here?

tusharmath avatar Dec 12 '23 14:12 tusharmath

can't we use leverage enums here?

Do you mean for the upstream ids?

sujeetsr avatar Dec 12 '23 14:12 sujeetsr

Yes.

tusharmath avatar Dec 12 '23 16:12 tusharmath

Action required: Issue inactive for 30 days. Status update or closure in 7 days.

github-actions[bot] avatar Jan 11 '24 17:01 github-actions[bot]

Action required: Issue inactive for 30 days. Status update or closure in 7 days.

github-actions[bot] avatar Feb 11 '24 10:02 github-actions[bot]

Issue closed after 7 days of inactivity.

github-actions[bot] avatar Feb 18 '24 11:02 github-actions[bot]

Is this dead? is there a plan to add this feature?

gonzalezzfelipe avatar Apr 17 '24 19:04 gonzalezzfelipe