ecyrbe / zodios

typescript http client and server with zod validation
https://www.zodios.org/
MIT License
1.71k stars 46 forks source link

API shorthand definition #142

Closed thelinuxlich closed 2 years ago

thelinuxlich commented 2 years ago

I feel like the API for declaring parameters could be simplified, it seems a bit verbose:

apiBuilder({
  path: '/marketplaces/:id/transactions',
  method: 'get',
  alias: 'getMarketplaceTransactions',
  // if it were a POST
  body: {
    .....
  },
  queries: {
      limit: z.number().optional()
      offset: z.number().optional()
      'date_range[gte]': z.string().optional()
      'date_range[lte]': z.string().optional()
  },
  headers: {
    Authorization: z.string()
  },
  // if the user really wants description for openAPI:
  description: {
     queries: {
        limit: 'A parameter to limit the number of rows returned'
     }
  },
  response: transactionsSchema,
})

Besides being less verbose, the parameter types have the same name as the objects in the API client (queries, headers) so it's intuitive

ecyrbe commented 2 years ago

Sorry, the design of endpoint definition is now stable and won't change as this would be a breaking change for all users.

But you could create a an helper function that transform the definition for you in current format.

ecyrbe commented 2 years ago

you can take a look at this if you want to transform it : https://github.com/ecyrbe/zodios/blob/main/src/api.ts#L84

thelinuxlich commented 2 years ago

By the way, asApi and apiBuilder seems a bit redundant, when should someone choose asApi?

ecyrbe commented 2 years ago

It's really a convenient choice. with apiBuilder, since you create one endpoint at a time, you have better autocompletion when creating endpoints. asAPI on the other end will fail to autocomplete sometimes (typescript fails to understand we are constructing a tuple and instead thinks we are constructing an array). So i'll recommand using apiBuilder when you are creating an api definition, and use asApi when combining multiple definitions.

// in one file
const userAPI = apiBuilder(...).build();
// in another file
const blogAPI = apiBuilder(...).build();
// in another
const fullAPI = asApi([...userAPI, ...blogAPI]);
ecyrbe commented 2 years ago

moving this issue discussion. if someone wants to contribute to it.