2. Frontend - Refzlund/sveltekit-zero-api GitHub Wiki
Note: Run npm run dev to generate api.ts
Types are generated when the server is running, so if a type isn't there. Edge-case; start/restart the dev server.
On the front-end you can access your api by importing it, and it will have type-safety all the way.
import api from '$src/api'api.ts is a generated file by Zero API. It will include the type and functions for the whole operation.
If we have src/routes/api/products/+server.ts as an endpoint with a POST, we can access it as api.products.POST
The api will automatically pick up the paramters for the endpoint.
If you await an api function such as api.products.GET(), you will get a Response (unless you're using .$.).
let response = await api.products.GET()
if(response.status == 200)
console.log(response.body)
// eqv. to
api.products.GET().ok(r => console.log(r.body))If you have a route like
src/routes/api/products/[warehouse]/storage/[product]/+server.ts
You can access this by using
api.products.warehouse$('austin-warehouse').storage.product$(productId).GET()In SvelteKit, the load functions has its own fetch which you can pass to the api.
If running an api call on the client and server, without providing a fetch function as the second argument — the api will only be called on the client.
import type { PageLoad } from './$types'
export const load: PageLoad = async ({ params, fetch }) => {
const { id } = params
// Pass `fetch` as the second argument
const response = await api.products.id$(id).GET({}, fetch)
return {
status: response.status,
props: {
product: response.ok && response.body
}
}
}For every response in your endpoint, there will be a callback function. If your backend returns
return Ok({ body: { message: 'Hello there' } })Then you can access it doing:
api.product.GET().ok(response => { console.log(response.body.message) })Every response-code has their own callback
Ok: 200 // .Ok(response => )
BadRequest: 400 // .BadRequest(response => )
InternalError: 500 // .InternalError(response => )And some callbacks cover more:
Any: xxx // .Any(r => )
Informational: 1xx // .Informational(r => )
Success: 2xx // .Success(r => )
Redirect: 3xx // .Redirect(r => )
ClientError: 4xx // .ClientError(r => )
ServerError: 5xx // .ServerError(r => )
Error: 4xx or 5xx // .Error(r => )if(A)
return Ok({ body: { message: 'Hello there', lol: false } })
else
return Created({ body: { message: 'Message created', product: someProduct, lol: true } })
// Side-note: Any Error response (4xx/5xx), have { error: string, target: any }
// as optional options. They will be in response: { body: { error, target } }
// If error isn't populated, the error message will be it's name f.i. "error: 'Internal Error'"
return InternalError({ error: 'Something went wrong' })Here you'll find the types:
api.product.GET()
// { body: { message: string, lol: boolean }, ... }
.Ok(response => {
const {
message, ✅
product, ⛔
lol ✅
} = response.body
})
// { body: { message: string, product: ProductType, lol: boolean }, ... }
.Created(({ body }) => {
const {
message, ✅
product, ✅
lol ✅
} = body
})
// { body: { error: string }, ... }
.InternalError(r => console.error(r.body.error)) ✅
.Success(r => {
let body = r.body
// All Success responses have { body: { message: string } }
body.message ✅
// Not all have product
body.product ⛔
if(!('product' in body)) // Return if 'product'-key is not in body
return
// Because we checked if product is in body, it is now valid
body.product ✅
})These functions will also be called in order. So
- Ok
- Success
or
- Created
- Success
In case of 200 (Ok) or 201 (Created)
If an endpoint does not return a status-code, but you still want a callback use ._. wildcard:
api.product.GET()._.UnavailableForLegalReasons(handleError)An exception to getting a Promise<Response>, is using the wildcard .$.
This returns whatever is returned from the trailing callback. Naturally, only one is allowed. And is only allowed in the end of the function.
If the return isn't an Ok, then it returns undefined.
// products: Product[] | undefined
let products = await api.product.GET().$.Ok(r => r.body)
if(!products) {
console.error('Did not receive any products.')
return
}
import type { ResponseBody, RequestParams } from 'sveltekit-zero-api/helpers'ResponseBody gets the body of a response, for a specific status-code.
// Where response: { body: { products: Product[] } }
let products: ResponseBody<typeof api.products.GET, 'Ok'>['products']
let productParams: RequestParams<typeof api.products.POST> = {
body: { productName: 'Banana' },
query: { value: 69.101 }
}