Skip to content

Commit

Permalink
resource routes
Browse files Browse the repository at this point in the history
  • Loading branch information
kentcdodds committed Nov 28, 2021
1 parent b5b139a commit 514d834
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 64 deletions.
65 changes: 1 addition & 64 deletions app/other-routes.server.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,12 @@
import {EntryContext, json} from 'remix'
import type {EntryContext} from 'remix'
import {getSitemapXml} from './utils/sitemap.server'
import {getRssFeedXml} from './utils/blog-rss-feed.server'
import {getAllUserData, prismaRead} from './utils/prisma.server'
import {commitShaKey as refreshCacheCommitShaKey} from './routes/action/refresh-cache'
import {redisCache} from './utils/redis.server'
import {requireUser} from './utils/session.server'
import {getUserInfo} from './utils/user-info.server'
import {getBlogReadRankings, getPostJson} from './utils/blog.server'

type Handler = (
request: Request,
remixContext: EntryContext,
) => Promise<Response | null> | null

// Just made it this way to make it easier to check for handled routes in
// our `routes/$slug.tsx` catch-all route.
const pathedRoutes: Record<string, Handler> = {
'/refresh-commit-sha.json': async () => {
const shaInfo = await redisCache.get(refreshCacheCommitShaKey)
const data = JSON.stringify(shaInfo)
return new Response(data, {
headers: {
'Content-Type': 'application/json',
'Content-Length': String(Buffer.byteLength(data)),
},
})
},
'/blog.json': async request => {
const data = await getPostJson(request)
const string = JSON.stringify(data)
return new Response(string, {
headers: {
'Content-Type': 'application/json',
'Content-Length': String(Buffer.byteLength(string)),
},
})
},
'/blog/rss.xml': async request => {
const rss = await getRssFeedXml(request)
return new Response(rss, {
headers: {
'Content-Type': 'application/xml',
'Content-Length': String(Buffer.byteLength(rss)),
},
})
},
'/sitemap.xml': async (request, remixContext) => {
const sitemap = await getSitemapXml(request, remixContext)
return new Response(sitemap, {
Expand All @@ -54,31 +16,6 @@ const pathedRoutes: Record<string, Handler> = {
},
})
},
'/me/download.json': async request => {
const user = await requireUser(request)

const postgres = await getAllUserData(user.id)
const cache = await getUserInfo(user, {request})
return json({postgres, cache})
},
'/healthcheck': async request => {
const host =
request.headers.get('X-Forwarded-Host') ?? request.headers.get('host')

try {
await Promise.all([
prismaRead.user.count(),
getBlogReadRankings({request}),
fetch(`http://${host}`, {method: 'HEAD'}).then(r => {
if (!r.ok) return Promise.reject(r)
}),
])
return new Response('OK')
} catch (error: unknown) {
console.log('healthcheck ❌', {error})
return new Response('ERROR', {status: 500})
}
},
}

const routes: Array<Handler> = [
Expand Down
57 changes: 57 additions & 0 deletions app/routes/blog.rss[.]xml.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type {LoaderFunction} from 'remix'
import * as dateFns from 'date-fns'
import {getBlogMdxListItems} from '~/utils/mdx'
import {getDomainUrl} from '~/utils/misc'

export const loader: LoaderFunction = async ({request}) => {
const posts = await getBlogMdxListItems({request})

const blogUrl = `${getDomainUrl(request)}/blog`

const rss = `
<rss xmlns:blogChannel="${blogUrl}" version="2.0">
<channel>
<title>Kent C. Dodds Blog</title>
<link>${blogUrl}</link>
<description>The Kent C. Dodds Blog</description>
<language>en-us</language>
<generator>Kody the Koala</generator>
<ttl>40</ttl>
${posts
.map(post =>
`
<item>
<title>${cdata(post.frontmatter.title ?? 'Untitled Post')}</title>
<description>${cdata(
post.frontmatter.description ?? 'This post is... indescribable',
)}</description>
<pubDate>${dateFns.format(
dateFns.add(
post.frontmatter.date
? dateFns.parseISO(post.frontmatter.date)
: Date.now(),
{minutes: new Date().getTimezoneOffset()},
),
'yyyy-MM-ii',
)}</pubDate>
<link>${blogUrl}/${post.slug}</link>
<guid>${blogUrl}/${post.slug}</guid>
</item>
`.trim(),
)
.join('\n')}
</channel>
</rss>
`.trim()

return new Response(rss, {
headers: {
'Content-Type': 'application/xml',
'Content-Length': String(Buffer.byteLength(rss)),
},
})
}

function cdata(s: string) {
return `<![CDATA[${s}]]>`
}
13 changes: 13 additions & 0 deletions app/routes/blog[.]json.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type {LoaderFunction} from 'remix'
import {getPostJson} from '~/utils/blog.server'

export const loader: LoaderFunction = async ({request}) => {
const data = await getPostJson(request)
const string = JSON.stringify(data)
return new Response(string, {
headers: {
'Content-Type': 'application/json',
'Content-Length': String(Buffer.byteLength(string)),
},
})
}
22 changes: 22 additions & 0 deletions app/routes/healthcheck.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type {LoaderFunction} from 'remix'
import {prismaRead} from '~/utils/prisma.server'
import {getBlogReadRankings} from '~/utils/blog.server'

export const loader: LoaderFunction = async ({request}) => {
const host =
request.headers.get('X-Forwarded-Host') ?? request.headers.get('host')

try {
await Promise.all([
prismaRead.user.count(),
getBlogReadRankings({request}),
fetch(`http://${host}`, {method: 'HEAD'}).then(r => {
if (!r.ok) return Promise.reject(r)
}),
])
return new Response('OK')
} catch (error: unknown) {
console.log('healthcheck ❌', {error})
return new Response('ERROR', {status: 500})
}
}
13 changes: 13 additions & 0 deletions app/routes/me/download[.]json.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type {LoaderFunction} from 'remix'
import {json} from 'remix'
import {getAllUserData} from '~/utils/prisma.server'
import {requireUser} from '~/utils/session.server'
import {getUserInfo} from '~/utils/user-info.server'

export const loader: LoaderFunction = async ({request}) => {
const user = await requireUser(request)

const postgres = await getAllUserData(user.id)
const cache = await getUserInfo(user, {request})
return json({postgres, cache})
}
14 changes: 14 additions & 0 deletions app/routes/refresh-commit-sha[.]json.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type {LoaderFunction} from 'remix'
import {redisCache} from '~/utils/redis.server'
import {commitShaKey as refreshCacheCommitShaKey} from './action/refresh-cache'

export const loader: LoaderFunction = async () => {
const shaInfo = await redisCache.get(refreshCacheCommitShaKey)
const data = JSON.stringify(shaInfo)
return new Response(data, {
headers: {
'Content-Type': 'application/json',
'Content-Length': String(Buffer.byteLength(data)),
},
})
}

0 comments on commit 514d834

Please sign in to comment.