-
Notifications
You must be signed in to change notification settings - Fork 15
refactor: use zod-openapi for ensnode-api #1672
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import { createRoute } from "@hono/zod-openapi"; | ||
|
|
||
| import { | ||
| makeEnsApiIndexingStatusResponseErrorSchema, | ||
| makeSerializedEnsApiIndexingStatusResponseOkSchema, | ||
| makeSerializedEnsApiPublicConfigSchema, | ||
| } from "@ensnode/ensnode-sdk/internal"; | ||
|
|
||
| export const basePath = "/api"; | ||
|
|
||
| export const getConfigRoute = createRoute({ | ||
| method: "get", | ||
| path: "/config", | ||
| tags: ["Meta"], | ||
| summary: "Get ENSApi Public Config", | ||
| description: "Gets the public config of the ENSApi instance", | ||
| responses: { | ||
| 200: { | ||
| description: "Successfully retrieved ENSApi public config", | ||
| content: { | ||
| "application/json": { | ||
| schema: makeSerializedEnsApiPublicConfigSchema(), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
notrab marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
|
|
||
| export const getIndexingStatusRoute = createRoute({ | ||
| method: "get", | ||
| path: "/indexing-status", | ||
| tags: ["Meta"], | ||
| summary: "Get ENSIndexer Indexing Status", | ||
| description: "Returns the indexing status snapshot most recently captured from ENSIndexer", | ||
| responses: { | ||
| 200: { | ||
| description: "Successfully retrieved indexing status", | ||
| content: { | ||
| "application/json": { | ||
| schema: makeSerializedEnsApiIndexingStatusResponseOkSchema(), | ||
| }, | ||
| }, | ||
| }, | ||
| 503: { | ||
| description: "Indexing status snapshot unavailable", | ||
| content: { | ||
| "application/json": { | ||
| schema: makeEnsApiIndexingStatusResponseErrorSchema(), | ||
| }, | ||
| }, | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }, | ||
| }, | ||
notrab marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
notrab marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| export const routes = [getConfigRoute, getIndexingStatusRoute]; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,101 +1,53 @@ | ||
| import config from "@/config"; | ||
|
|
||
| import { describeRoute, resolver as validationResolver } from "hono-openapi"; | ||
|
|
||
| import { | ||
| IndexingStatusResponseCodes, | ||
| type IndexingStatusResponseError, | ||
| type IndexingStatusResponseOk, | ||
| EnsApiIndexingStatusResponseCodes, | ||
| type EnsApiIndexingStatusResponseError, | ||
| type EnsApiIndexingStatusResponseOk, | ||
| serializeENSApiPublicConfig, | ||
| serializeIndexingStatusResponse, | ||
| serializeEnsApiIndexingStatusResponse, | ||
| } from "@ensnode/ensnode-sdk"; | ||
| import { | ||
| makeENSApiPublicConfigSchema, | ||
| makeIndexingStatusResponseSchema, | ||
| } from "@ensnode/ensnode-sdk/internal"; | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I note an inconsistency here. For example: I see: ... for many APIs. But why isn't this pattern followed for the "meta" API handlers for getting the config or indexing status (which are the "meta" APIs)? Why are these API handlers defined directly in this file while no other APIs are directly implemented in this file?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lightwalker-eth this was pre-existing inconsistency which is why I did not refactor it at this stage. I only refactored the meta handlers from |
||
| import { buildEnsApiPublicConfig } from "@/config/config.schema"; | ||
| import { factory } from "@/lib/hono-factory"; | ||
| import { createApp } from "@/lib/hono-factory"; | ||
|
|
||
| import { getConfigRoute, getIndexingStatusRoute } from "./ensnode-api.routes"; | ||
| import ensnodeGraphQLApi from "./ensnode-graphql-api"; | ||
| import nameTokensApi from "./name-tokens-api"; | ||
| import registrarActionsApi from "./registrar-actions-api"; | ||
| import resolutionApi from "./resolution-api"; | ||
|
|
||
| const app = factory.createApp(); | ||
| const app = createApp(); | ||
|
|
||
| app.get( | ||
| "/config", | ||
| describeRoute({ | ||
| tags: ["Meta"], | ||
| summary: "Get ENSApi Public Config", | ||
| description: "Gets the public config of the ENSApi instance", | ||
| responses: { | ||
| 200: { | ||
| description: "Successfully retrieved ENSApi public config", | ||
| content: { | ||
| "application/json": { | ||
| schema: validationResolver(makeENSApiPublicConfigSchema()), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }), | ||
| async (c) => { | ||
| const ensApiPublicConfig = buildEnsApiPublicConfig(config); | ||
| return c.json(serializeENSApiPublicConfig(ensApiPublicConfig)); | ||
| }, | ||
| ); | ||
| app.openapi(getConfigRoute, async (c) => { | ||
| const ensApiPublicConfig = buildEnsApiPublicConfig(config); | ||
| return c.json(serializeENSApiPublicConfig(ensApiPublicConfig)); | ||
| }); | ||
|
|
||
| app.get( | ||
| "/indexing-status", | ||
| describeRoute({ | ||
| tags: ["Meta"], | ||
| summary: "Get ENSIndexer Indexing Status", | ||
| description: "Returns the indexing status snapshot most recently captured from ENSIndexer", | ||
| responses: { | ||
| 200: { | ||
| description: "Successfully retrieved indexing status", | ||
| content: { | ||
| "application/json": { | ||
| schema: validationResolver(makeIndexingStatusResponseSchema()), | ||
| }, | ||
| }, | ||
| }, | ||
| 503: { | ||
| description: "Indexing status snapshot unavailable", | ||
| content: { | ||
| "application/json": { | ||
| schema: validationResolver(makeIndexingStatusResponseSchema()), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }), | ||
| async (c) => { | ||
| // context must be set by the required middleware | ||
| if (c.var.indexingStatus === undefined) { | ||
| throw new Error(`Invariant(indexing-status): indexingStatusMiddleware required`); | ||
| } | ||
| app.openapi(getIndexingStatusRoute, async (c) => { | ||
| // context must be set by the required middleware | ||
| if (c.var.indexingStatus === undefined) { | ||
| throw new Error(`Invariant(indexing-status): indexingStatusMiddleware required`); | ||
| } | ||
|
|
||
| if (c.var.indexingStatus instanceof Error) { | ||
| return c.json( | ||
| serializeIndexingStatusResponse({ | ||
| responseCode: IndexingStatusResponseCodes.Error, | ||
| } satisfies IndexingStatusResponseError), | ||
| 503, | ||
| ); | ||
| } | ||
|
|
||
| // return successful response using the indexing status projection from the middleware context | ||
| if (c.var.indexingStatus instanceof Error) { | ||
| return c.json( | ||
| serializeIndexingStatusResponse({ | ||
| responseCode: IndexingStatusResponseCodes.Ok, | ||
| realtimeProjection: c.var.indexingStatus, | ||
| } satisfies IndexingStatusResponseOk), | ||
| serializeEnsApiIndexingStatusResponse({ | ||
| responseCode: EnsApiIndexingStatusResponseCodes.Error, | ||
| } satisfies EnsApiIndexingStatusResponseError), | ||
| 503, | ||
| ); | ||
| }, | ||
| ); | ||
| } | ||
|
|
||
| // return successful response using the indexing status projection from the middleware context | ||
| return c.json( | ||
| serializeEnsApiIndexingStatusResponse({ | ||
| responseCode: EnsApiIndexingStatusResponseCodes.Ok, | ||
| realtimeProjection: c.var.indexingStatus, | ||
| } satisfies EnsApiIndexingStatusResponseOk), | ||
| 200, | ||
| ); | ||
| }); | ||
|
|
||
| // Name Tokens API | ||
| app.route("/name-tokens", nameTokensApi); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's rename this file to
meta.routes.tsas all the routes here represent "meta" routes that return various metadata.