Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request ] - Pylon without web server. #50

Open
ShanonJackson opened this issue Nov 7, 2024 · 5 comments
Open

[Feature Request ] - Pylon without web server. #50

ShanonJackson opened this issue Nov 7, 2024 · 5 comments
Labels
🚦 status: awaiting triage Has not been triaged & therefore, not ready for work

Comments

@ShanonJackson
Copy link

ShanonJackson commented Nov 7, 2024

Is your feature request related to a problem? Please describe.
Would love access to opportunity to use pylon in a way that still allows me native control of the underlying http server.

const app = new Hono(<opportunity to configure here>)
// <various app logic 
Bun.serve({
	port: Number(process.env.PORT || 3001),
	idleTimeout: 120,
	fetch: (request, ctx) => {
	        // some programmatic logic here.
	        // opportunity to use pylon here.
		return app.fetch(request, ctx);
	},
});

This has the following advantages:

  • Potential to use pylon in other web frameworks that aren't Hono.
  • Potential for people to integrate pylon into brownfield apps more easily.
  • Simplifies documentation / maintenance because all documentation relating to the "web server" component can be removed or kept for backwards compatibility in another section; Or 'in parallel compatibility'.
  • Potential to configure idleTimeout (https://bun.sh/docs/api/http#idletimeout) which prevents slow loris attack and solve other problems.
  • Potential to configure PORT as environment variable including the environment variables name which simplifies the pylon command.
  • Potential to use different commands for dev I.E
"dev": "pylon dev -c \"bun run .pylon/index.js\" --client --client-port 3003 --client-path gqty\\index.ts",
// becomes
"dev": "bun run --watch ./src/server.ts"
  • Simplifies docker entry point command.
  • Potential to use pylon (graphql) in environments outside of http I.E udp, LoRA, etc.

The summary of above is it would provide people to separate "pylon" from the underlying "runtime" and "web framework" allowing more flexibility to developers.

Issues and simplifications

export const graphql = { Query: { hello: () => 'Hello World'}, Mutation: {} }

This syntax would potentially need to expose a type of a function that matches the app.fetch signature from Hono. I see this though as an improvement because it would allow people to create different adapters for different web frameworks.
I.E

export const graphql = { Query: { hello: () => 'Hello World'}, Mutation: {} } 
export default graphql // existing setup non-breaking change stays the same.

// web server control way being proposed 
import { adapter } from "pylon/hono"; 
export const graphql = adapter({ Query: { hello: () => 'Hello World'}, Mutation: {} });

Which leaves room for express/elysia/node/etc adapters.

Adapters would setup a AsyncLocalStorage context, allowing developers to set getContext and potential to use that (request storage context) for other properties/state I.E tracing etc.

resloves

#9
#21 (because can leverage existing auth strategy's in underlying web framework)

@schettn schettn added the 🚦 status: awaiting triage Has not been triaged & therefore, not ready for work label Nov 9, 2024
@schettn
Copy link
Contributor

schettn commented Nov 9, 2024

Hi @ShanonJackson!

Thank you for your interesting request. I need to give this deeper thought to determine how a more "general" approach would be feasible, considering Pylon aims to be a framework that simplifies development rather than a universal library for all frameworks.

Here's what I can say for now:

  • Pylon's dev command is designed this way because it relies on a prebuild step for schema and client generation. That's why you need to execute .pylon/index.js. I'm not sure if it's technically possible to change that at this point.
  • You already have control over the "server." The proposed Bun.serve command works out of the box, so you can configure idleTimeout, PORT as an environment variable, etc.

Could you elaborate on how this would fix issue #9?

@ShanonJackson
Copy link
Author

ShanonJackson commented Nov 9, 2024

for #9

app.post("/2024-10-10/graphql", adapter({
    Query: {
          resource: () => "hello 2024-10-10"
     }
}, {output: "2024-10-10.schema.graphql"});
app.post("/graphql", adapter({
    Query: {
          resource: () => "hello original"
     }
}, {output: "schema.graphql" /* default */});

and via spread to override a specific resource without rewriting the whole graphql constant.

const gql = graphql({Query: {resource: () => "hello non versioned"});
app.post("/2024-10-10/graphql", adapter({...gql, Query: {...gql.Query, resource: "hello 2024-10-10"}})); // with "resource" overridden but everything else same.
app.post("/graphql", adapter(gql));

This way you can create new versions of specific resources and/or entire new graphql schemas using whatever version system you desire. I.E standard api numerical based versioning or by date.

Obivously above syntax requires outputting

Pylon's dev command is designed this way because it relies on a prebuild step for schema and client generation

For this yes, the intention was to decouple this "prebuild step" from the dev command itself and run it as an entirely separate command.

I.E pylon generate --watch dev would be concurrently watch and serve. Not that I'm a fan of saying "here they do x" but in most code gen based tooling they have decoupled watch commands.

You already have control over the "server." The proposed Bun.serve

Can you show me the syntax for this?

@schettn
Copy link
Contributor

schettn commented Nov 11, 2024

Can you show me the syntax for this?

import {app} from '@getcronit/pylon'

export const graphql = {
  Query: {
    test: () => 'Hello, world!'
  }
}

export default app

const server = Bun.serve({
  fetch: app.fetch,
  port: 4000,
  idleTimeout: 120
})

console.log(`Server running at ${server.url}`)

@schettn
Copy link
Contributor

schettn commented Nov 11, 2024

for #9

#9 is not just about configuring date based routes, but rather automatic backwards compatible versioning handled by Pylon. Related to #8.

So for example when you release a API with a a test query and later remove the test query, it will still be available in old version endpoint, but no longer in latest.
This should then be the case with all breaking changes that you introduce in your pylon application.

@schettn
Copy link
Contributor

schettn commented Nov 26, 2024

Hi @ShanonJackson.

I just released a new feature that allows setting up the graphql routes manually.

This is mainly used for dependency mocking during test, but is also the first step to be more framework agnostic.

https://pylon.cronit.io/docs/guides/testing#optional-mocking-dependencies

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚦 status: awaiting triage Has not been triaged & therefore, not ready for work
Projects
None yet
Development

No branches or pull requests

2 participants