loolabs / waterpark

Waterloo's social park
http://waterpark.loo-labs.vercel.app
ISC License
4 stars 0 forks source link

πŸ—„οΈ Create express API type system based off OpenAPI #194

Closed xujustinj closed 3 years ago

xujustinj commented 3 years ago

Purpose

Part of #42.

I kept trying to integrate the stuff from #85 with waterpark, but my changes became outdated each time we advanced main (or each time I decided to change the API type system).

This PR attempts to lock in a final-for-now type system. schema.ts defines the main structure of an API. Roughly speaking, it is a subset of the OpenAPI Paths object.

How does this affect you? Someday, your Waterpark types will be imported from the /common/src/waterpark/ folder.

Approach

The OpenAPI standard (a.k.a. Swagger, which we might use someday to externally document our APIs) is quite different from what I put in #85. The most jarring difference is that paths are not recursive (/washrooms/:id/ is not a child of /washrooms/). This prevents us from nesting routers (for now), but it also makes the type system more readable, and allows for flatter schema objects.

Also, OpenAPI resolves some of the discussions from #85 about whether to call something an API or an endpoint. It refers to things as "paths", where each path has one or more "operations". It sounded weird to me at first, but then it grew on me.

Testing

Ran npm run build in /common/ and it worked.

If you checkout the code, take a look at demo.ts to see that the compiler now gives types to the req and res objects. You can also verify that various invalid router calls get blocked by the compiler.

router.get('/washrooms/', (_, res) => {
  res.json({ this: 'is not a valid response from GET /washrooms/' })
})

router.get('/not-a-path/', (_, _) => {})

// technically still works, but req and res will contain `never` types
// because there is no POST endpoint for this path
router.post('/washrooms/:id/', (req, res) => {
  // do stuff
})

image

TODOs

The code in /common/ is not-at-all integrated with /server/. There are plenty of Docker nightmares coming in the future when we do integrate it, but that is not a concern for now.

Still not entirely sure what the frontend equivalent of typexpress would be.

vercel[bot] commented 3 years ago

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

πŸ” Inspect: https://vercel.com/loo-labs/waterpark/ASBUrnn61krdgWyo6mYAFUWWFvX5
βœ… Preview: https://waterpark-git-api-types-loo-labs.vercel.app