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

feat: Validate Vercel cron paths #9145

Merged
merged 15 commits into from
Feb 28, 2023
Merged

Conversation

elliott-with-the-longest-name-on-github
Copy link
Contributor

Vercel Cron Jobs are launching. Thanks to their API, we don't actually have to make any changes to support them. However, as a courtesy to our users, we can make sure that a SvelteKit app exports a GET API handler that matches the path for each cron job. We can't do more than warn here, as users could handle these requests in handle, but I think the normal usecase would be to define a +server.ts endpoint.

  • Is there a way to test this?
  • Do we want to enable suppression of these warnings via a config option?

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
@@ -51,6 +51,7 @@ export function create_builder({
/** @type {import('types').RouteDefinition} */
const facade = {
id: route.id,
type: route.endpoint ? 'endpoint' : 'page',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it needs to be a pair of booleans, not an enum — a route can have both +page and +server (in which case we do content negotiation)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design wise I think this should be an enum with three values. Two booleans is incorrect in the sense that both can never be false at the same time

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not future-proof — if we added a third route type (socket or something?), both would no longer make sense. Booleans are a better reflection of the types we use internally (where we went down this road before and switched to booleans because of the content negotiation thing)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried again with booleans. Should the condition for hasPage be as simple as it is?

Also, is there a way around not false-positive-ing on a route with a page and an endpoint with a method other than GET?

Copy link
Member

@Rich-Harris Rich-Harris Feb 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point re false positives. I guess we would need to do something like

{
  pageMethods: ['GET', 'POST'],
  endpointMethods: ['DELETE']
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that solution. Let me investigate.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, is it possible for a page to have anything but GET?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, if it has form actions

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented and pushed. I went with a slightly different object structure:

{
  endpoint: { methods: [] },
  page: { methods: [] }
}

Happy tochange it to the keys you suggested -- this just seemed more likely to grow without warts in the future.

@Smirow
Copy link

Smirow commented Feb 22, 2023

Should it be considered to add cron in route level config when it gets out of beta as it is supported by the Build Output API?

@Rich-Harris
Copy link
Member

Should it be considered to add cron in route level config

That's what Next is doing but I think it's the wrong approach — if used with a route with dynamic params, then you need some mechanism for specifying paths in the config, and then you have the absurd possibility that a function could specify paths that don't belong to it.

It also means that you specify cron tasks in a SvelteKit project differently to how you do it for every other framework, which means more documentation and confusion. Much simpler to just use vercel.json.

@Smirow
Copy link

Smirow commented Feb 22, 2023

Should it be considered to add cron in route level config

That's what Next is doing but I think it's the wrong approach — if used with a route with dynamic params, then you need some mechanism for specifying paths in the config, and then you have the absurd possibility that a function could specify paths that don't belong to it.

It also means that you specify cron tasks in a SvelteKit project differently to how you do it for every other framework, which means more documentation and confusion. Much simpler to just use vercel.json.

Yes it completely breaks down when you need dynamic params.

@dummdidumm
Copy link
Member

If this makes use of a new adapter API it needs to be a major version bump for adapter-vercel, which I'd like to avoid. Can we code it such that the validation only happens if you have a recent enough SvelteKit version which contains these APIs?

@Smirow
Copy link

Smirow commented Feb 23, 2023

Is it necessary to trigger that warning? I feel it's kinda strange to only check for cron as the user can define other configs in vercel.json that are not checked by the adapter.

@elliott-with-the-longest-name-on-github
Copy link
Contributor Author

It's not strictly necessary, but it is helpful -- and without the warning it's a potentially confusing issue. And I'm not really sure what other vercel.json stuff we would want to validate. We're not checking whether it's valid from a Vercel standpoint -- we're checking it's going to interact with your app in a valid way.

@elliott-with-the-longest-name-on-github
Copy link
Contributor Author

@dummdidumm any ideas? The obvious one is:

// Remove this check for v3
if (routes.endpoints !== undefined) {
  // Code
}

Copy link
Member

@Rich-Harris Rich-Harris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have made it backwards-compatible.

Code looks fine now, but I'm uneasy about exposing endpoint in a public API. It's terminology that still appears in the docs in a few places but we had generally decided to stop using it in favour of 'API route' which is more common. I still think route.server would be the best option (route.server and route.page corresponds to +server and +page), but route.api could also work.

@elliott-with-the-longest-name-on-github
Copy link
Contributor Author

I'm more in favor of route.api than I am route.server -- mainly because server could potentially mean "has a +page.server.ts". It's not a huge deal either way, though. I'll defer to you and @dummdidumm on naming and implement whatever you can both agree on.

@dummdidumm
Copy link
Member

dummdidumm commented Feb 27, 2023

I vote for api if we want to call it API routes
(code looks good to me otherwise)

@Rich-Harris
Copy link
Member

api it is!

@Rich-Harris Rich-Harris merged commit 1f4b87e into master Feb 28, 2023
@Rich-Harris Rich-Harris deleted the elliott/vercel-cron-validation branch February 28, 2023 01:17
@github-actions github-actions bot mentioned this pull request Feb 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants