Fastify
Routes
Yol yöntemleri uygulamanızın uç noktalarını yapılandıracaktır. Fastify ile bir rotayı iki yolla tanımlayabilirsiniz: kısayol yöntemi ve tam açıklama.
Tam açıklama
Rota seçenekleri
Kısayol açıklaması
Url oluşturma
Async Await
Promise çözümü
Rota Ön Ekleme
Ön ekli eklentiler içinde / rotasının işlenmesi
Özel Log Seviyesi
Özel Log Serileştirici
Yapılandırma
Kısıtlamalar
Versiyon Kısıtlamaları
Host Kısıtlamaları
Tam açıklama
fastify.route(options)
Rota seçenekleri
method
: şu andaGET
,HEAD
,TRACE
,DELETE
,OPTIONS
,PATCH
,PUT
vePOST
desteklenmektedir. Daha fazla yöntem kabul etmek için,addHttpMethod
kullanılmalıdır. Bu ayrıca bir yöntemler dizisi olabilir.url
: bu rotayı eşleştirmek için URL'nin yolu (takma ad:path
).schema
: istek ve cevap için şemaları içeren bir nesne. Bunlar JSON Şeması formatında olmalıdır, daha fazla bilgi içinburaya
bakın.body
: POST, PUT, PATCH, TRACE, SEARCH, PROPFIND, PROPPATCH veya LOCK yöntemi ise isteğin gövdesini doğrular.querystring
veyaquery
: sorgu dizesini doğrular. Bu,object
türü içintype
özelliği içeren bir JSON Şeması nesnesi veya aşağıda gösterildiği gibiproperties
nesnesinde yer alacak değerler olabilir.params
: parametreleri doğrular.response
: cevabı filtreleme ve bir şema oluşturma, bir şema belirlemek bize %10-20 daha fazla verimlilik sağlar.
exposeHeadRoute
: herhangi birGET
rotası için bir kardeşHEAD
rotası oluşturur. Varsayılan olarak,exposeHeadRoutes
örnek seçenek değeridir. Bu seçeneği devre dışı bırakmadan özel birHEAD
işleyicisi istiyorsanız,GET
rotasından önce bunu tanımladığınızdan emin olun.attachValidation
: isteğevalidationError
ekleyerek, bir şema doğrulama hatası varsa, hatayı hata işleyicisine göndermenin yerine. Varsayılan hata formatı Ajv formatındadır.onRequest(request, reply, done)
: geldiği anda çağrılan birfonksiyon
, bu bir dizi fonksiyon da olabilir.preParsing(request, reply, done)
: isteği ayrıştırmadan önce çağrılan birfonksiyon
, bu bir dizi fonksiyon da olabilir.preValidation(request, reply, done)
: paylaşılmışpreValidation
kancalarından sonra çağrılan birfonksiyon
, örneğin rota seviyesinde kimlik doğrulama yapılması gerektiğinde, bu bir dizi fonksiyon da olabilir.preHandler(request, reply, done)
: istek işleyicisinden önce çağrılan birfonksiyon
, bu bir dizi fonksiyon da olabilir.preSerialization(request, reply, payload, done)
: serileştirmeden önce çağrılan birfonksiyon
, bu bir dizi fonksiyon da olabilir.onSend(request, reply, payload, done)
: bir cevabı göndermeden hemen önce çağrılan birfonksiyon
, bu bir dizi fonksiyon da olabilir.onResponse(request, reply, done)
: bir cevap gönderildiğinde çağrılan birfonksiyon
, böylece istemciye daha fazla veri gönderemezsiniz. Bu bir dizi fonksiyon da olabilir.onTimeout(request, reply, done)
: bir isteğin zaman aşıma uğradığında ve HTTP soketi kapatıldığında çağrılan birfonksiyon
.onError(request, reply, error, done)
: bir hata oluştuğunda veya hata işleyicisi tarafından istemciye gönderildiğinde çağrılan birfonksiyon
.handler(request, reply)
: bu isteği işleyecek olan fonksiyondur.Fastify sunucusu
bu fonksiyon çağrıldığındathis
ile bağlanacaktır. Not: ok işlevi kullanmakthis
bağlamını bozacaktır.errorHandler(error, request, reply)
: isteğin kapsamı için özel bir hata işleyicisidir. Varsayılan hata küresel işleyicisini geçersiz kılar vesetErrorHandler
tarafından ayarlanan her şeyi, rotaya yapılan istekler için. Varsayılan işleyiciye erişmek için,instance.errorHandler
erişebilirsiniz. Bu sadece bir eklenti bunu zaten geçersiz kılmadıysa, Fastify'ın varsayılanerrorHandler
'ına işaret eder.childLoggerFactory(logger, binding, opts, rawReq)
: her istek için bir çocuk logger örneği üretmek üzere çağrılacak bir özel fabrika fonksiyonu. Daha fazla bilgi içinchildLoggerFactory
belgesine bakın. Varsayılan logger fabrikasını geçersiz kılar vesetChildLoggerFactory
tarafından ayarlanan her şeyi, rotaya yapılan istekler için. Varsayılan fabrikaya erişmek için,instance.childLoggerFactory
erişebilirsiniz. Bu sadece bir eklenti bunu zaten geçersiz kılmadıysa, Fastify'ın varsayılanchildLoggerFactory
'ına işaret eder.validatorCompiler({ schema, method, url, httpPart })
: istek doğrulama şemaları inşa eden bir fonksiyon.Doğrulama ve Serileştirme
belgelerine bakın.serializerCompiler({ { schema, method, url, httpStatus, contentType } })
: cevap serileştirme şemaları inşa eden bir fonksiyon.Doğrulama ve Serileştirme
belgelerine bakın.schemaErrorFormatter(errors, dataVar)
: doğrulama derleyicisinden gelen hataları formatlayan bir fonksiyon.Doğrulama ve Serileştirme
belgelerine bakın. Rotaya yapılan istekler için, küresel şema hata formatlayıcı işleyicisinden geçersiz kılar vesetSchemaErrorFormatter
ile ayarlanan her şeyi.bodyLimit
: bu sayıdan daha büyük istek gövdelerinin ayrıştırılmasını önler. Bir tam sayı olmalıdır. Bu seçeneği ilk Fastify örneğinifastify(options)
oluşturduğunuzda global olarak da ayarlayabilirsiniz. Varsayılan olarak1048576
(1 MiB) olarak ayarlıdır.logLevel
: bu rota için log seviyesini ayarlar. Aşağıda gözden geçirin.logSerializers
: bu rota için logcıları ayarlayın.config
: özel yapılandırma depolamak için kullanılan nesne.version
: uç noktanın versiyonunu tanımlayan bir semver uyumlu dize.Örnek
.constraints
: isteğe bağlı değerler veya özellikler temelinde rota sınırlamalarını tanımlar, find-my-way kısıtlamalarını kullanarak özelleştirilmiş eşleştirmeye olanak tanır. Yerleşikversion
vehost
kısıtlamaları ile birlikte özel kısıtlama stratejilerinin desteği vardır.prefixTrailingSlash
: bir rotayı öneki ile geçerken/
'in nasıl işleneceğini belirlemek için kullanılan dize.both
(varsayılan): Hem/prefix
hem de/prefix/
kaydedecektir.slash
: Sadece/prefix/
kaydedecektir.no-slash
: Sadece/prefix
kaydedecektir.
Not: Bu seçenek,
Server
yapılandırmasındaignoreTrailingSlash
'ı geçersiz kılmıyor.request
Request
içerisinde tanımlanmıştır.reply
Reply
içerisinde tanımlanmıştır.
Dikkat: onRequest
, preParsing
, preValidation
,
preHandler
, preSerialization
, onSend
ve onResponse
belgeleri daha ayrıntılı olarak
Hooks
içerisinde açıklanmaktadır. Ayrıca, bir cevabı handler
tarafından işlenmeden önce göndermek isterseniz, Bir
kancadan isteğe cevap verin
ile
başvurun.
Örnek:
fastify.route({
method: 'GET',
url: '/',
schema: {
querystring: {
type: 'object',
properties: {
name: { type: 'string' },
excitement: { type: 'integer' }
}
},
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
},
handler: function (request, reply) {
reply.send({ hello: 'world' })
}
})
Kısayol açıklaması
Yukarıdaki rota bildirimi daha Hapi'ye benzer, ancak bir Express/Restify yaklaşımını tercih ediyorsanız, bunu da destekliyoruz:
fastify.get(path, [options], handler)
fastify.head(path, [options], handler)
fastify.post(path, [options], handler)
fastify.put(path, [options], handler)
fastify.delete(path, [options], handler)
fastify.options(path, [options], handler)
fastify.patch(path, [options], handler)
Örnek:
const opts = {
schema: {
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
}
fastify.get('/', opts, (request, reply) => {
reply.send({ hello: 'world' })
})
fastify.all(path, [options], handler)
tüm desteklenen yöntemler için aynı işleyiciyi ekleyecektir.
İşleyici, options
nesnesi aracılığıyla da sağlanabilir:
const opts = {
schema: {
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
},
handler: function (request, reply) {
reply.send({ hello: 'world' })
}
}
fastify.get('/', opts)
Not: işleyici hem
options
içerisinde hem de kısayol metoduna üçüncü parametre olarak belirtilirse, tekrarlayan birhandler
hatası fırlatılır.
Url oluşturma
Fastify hem statik hem de dinamik URL'leri destekler.
Parametreli bir yolu kaydetmek için, parametre adının önüne nokta kullanın. Wildcard için, yıldız kullanın. Statik rotaların her zaman parametreli ve wildcard'tan önce kontrol edildiğini unutmayın.
// parametreli
fastify.get('/example/:userId', function (request, reply) {
// curl ${app-url}/example/12345
// userId === '12345'
const { userId } = request.params;
// kodunuzu buraya yazın
})
fastify.get('/example/:userId/:secretToken', function (request, reply) {
// curl ${app-url}/example/12345/abc.zHi
// userId === '12345'
// secretToken === 'abc.zHi'
const { userId, secretToken } = request.params;
// kodunuzu buraya yazın
})
// wildcard
fastify.get('/example/*', function (request, reply) {})
Düzenli ifade rotaları da desteklenmektedir, ancak eğrilere dikkat etmeniz gerekiyor. Düzenli işlemler de performans açısından oldukça masraflıdır!
// parametreli ve regexp ile
fastify.get('/example/:file(^\\d+).png', function (request, reply) {
// curl ${app-url}/example/12345.png
// file === '12345'
const { file } = request.params;
// kodunuzu buraya yazın
})
Aynı çift eğrinin içerisinde birden fazla parametre tanımlamak mümkündür:
fastify.get('/example/near/:lat-:lng/radius/:r', function (request, reply) {
// curl ${app-url}/example/near/15°N-30°E/radius/20
// lat === "15°N"
// lng === "30°E"
// r ==="20"
const { lat, lng, r } = request.params;
// kodunuzu buraya yazın
})
Bu durumda parametre ayırıcı olarak tire ("-") kullanmayı unutmayın.
Son olarak, düzenli ifade ile birden fazla parametreye sahip olabilirsiniz:
fastify.get('/example/at/:hour(^\\d{2})h:minute(^\\d{2})m', function (request, reply) {
// curl ${app-url}/example/at/08h24m
// hour === "08"
// minute === "24"
const { hour, minute } = request.params;
// kodunuzu buraya yazın
})
Bu durumda parametre ayırıcı olarak düzenli ifade ile eşleşmeyen herhangi bir karakter kullanılabilir.
Son parametreyi isteğe bağlı hale getirmek için parametre adının sonuna bir soru işareti ("?") ekleyin.
fastify.get('/example/posts/:id?', function (request, reply) {
const { id } = request.params;
// kodunuzu buraya yazın
})
Bu durumda /example/posts
ve /example/posts/1
isteği yapabilirsiniz.
İsteğe bağlı parametre belirtilmediği takdirde undefined olur.
Birden fazla parametreye sahip bir rota kullanmak performansı olumsuz etkileyebilir, bu nedenle mümkün olduğunca tek parametre yaklaşımını tercih edin, özellikle uygulamanızın sıcak rotalarında. Eğer yönlendirmeyi nasıl yönettiğimizle ilgileniyorsanız, find-my-way kontrol edin.
Bir parametre bildirmeden nokta içeren bir yol istiyorsanız, iki nokta kullanın. Örneğin:
fastify.post('/name::verb') // /name:verb olarak yorumlanır
Async Await
async/await
kullanıcısı mısınız? Sizin için düşündük!
fastify.get('/', options, async function (request, reply) {
const data = await getData()
const processed = await processData(data)
return processed
})
Gördüğünüz gibi, kullanıcıya veri göndermek için reply.send
çağırmıyoruz.
Gövdeyi yalnızca döndürmeniz yeterlidir ve işiniz biter!
Eğer gerekirse, kullanıcıya veriyi reply.send
ile de geri gönderebilirsiniz. Bu durumda, async
işleyicinizde
return reply
veya await reply
yazmayı unutmayın, aksi takdirde belirli durumlarda bir yarış durumu ortaya çıkabilirsiniz.
fastify.get('/', options, async function (request, reply) {
const data = await getData()
const processed = await processData(data)
return reply.send(processed)
})
Eğer rota bir çağrı tabanlı API ile sarma işini yapıyorsa ve reply.send()
'i
vaat zinciri dışında arıyorsanız, await reply
yapabilirsiniz:
fastify.get('/', options, async function (request, reply) {
setImmediate(() => {
reply.send({ hello: 'world' })
})
await reply
})
reply
ile geri dönmek de işe yarar:
fastify.get('/', options, async function (request, reply) {
setImmediate(() => {
reply.send({ hello: 'world' })
})
return reply
})
Uyarı:
- Hem
return value
hem dereply.send(value)
'i aynı anda kullanırken, gerçekleşen ilk üstünlük kazanır, ikinci değer iptal edilir ve iki kez yanıt vermeye çalıştığınız için bir warn günlük kaydı da yayılacaktır. - Vaat dışındaki
reply.send()
çağrısı mümkündür ama özel bir dikkat gerektirir. Daha fazla detay içinpromise-resolution
bölümüne bakın. undefined
döndüremezsiniz. Daha fazla detay içinpromise-resolution
bölümüne bakın.
Promise çözümü
Eğer işleyiciniz bir async
fonksiyonuysa veya bir vaatte bulunuyorsa,
geri çağrım ve vaad akış kontrolünü desteklemek için gerekli olan özel davranışların farkında olmalısınız.
İşleyicinin vaadi çözüldüğünde, yukarıdan otomatik olarak iletilecektir. Bu,
işleyicide reply
beklemeyi veya return
etmeyi açık bir şekilde yapmadığınız takdirde.
async/await
veya vadeler kullanmak ve bir değerle yanıt vermek istiyorsanız:- Yapın
return reply
/await reply
. - Yapmayın
reply.send
çağırmayı unutmayın.
- Yapın
async/await
veya vadeler kullanmak istiyorsanız:- Yapmayın
reply.send
kullanın. - Yapın göndermek istediğiniz değeri döndürün.
- Yapmayın
Bu şekilde, hem callback-style
hem de async-await
destekleyebiliriz,
minimum değişimle. Bu kadar özgürlükten dolayı, tüm bu tarzın birini
seçmenizi öneririz çünkü hata işleme uygulamanızda tutarlı bir şekilde
yapılmalıdır.
Dikkat: Her async fonksiyonu kendisi bir vaat döndürür.
Rota Ön Ekleme
Bazen aynı API'nin iki veya daha fazla sürümünü korumanız gerekebilir; klasik bir yaklaşım,
tüm rotaları API sürüm numarası ile öneklemektir, örneğin /v1/user
. Fastify,
tüm rota adlarını manuel olarak değiştirmeden, aynı API'nin farklı sürümlerini
hızlı ve akıllıca oluşturmanın bir yolunu sunar, rota öne ekleme. İşte nasıl çalıştığı:
// server.js
const fastify = require('fastify')()
fastify.register(require('./routes/v1/users'), { prefix: '/v1' })
fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
fastify.listen({ port: 3000 })
// routes/v1/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v1)
done()
}
// routes/v2/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v2)
done()
}
Fastify, iki farklı rota için aynı ismi kullandığınız için şikayet etmeyecektir, çünkü derleme zamanında öneki otomatik olarak yönetecektir (bu aynı zamanda performansı da etkilemeyecektir!).
Artık müşterileriniz aşağıdaki rotalara erişebilir:
/v1/user
/v2/user
Bunu istediğiniz kadar yapabilirsiniz, ayrıca iç içe register
için de çalışır ve
rota parametreleri desteklenir.
Tüm rotalarınız için önek kullanmak isterseniz, onları bir eklenti içinde koyabilirsiniz:
const fastify = require('fastify')()
const route = {
method: 'POST',
url: '/login',
handler: () => {},
schema: {},
}
fastify.register(function (app, _, done) {
app.get('/users', () => {})
app.route(route)
done()
}, { prefix: '/v1' }) // global rota öneki
await fastify.listen({ port: 3000 })
Rota Ön Ekleme ve fastify-plugin
Eğer yollarınızı sarmak için fastify-plugin
kullanıyorsanız,
bu seçenek çalışmayacaktır. Bunu bir eklentide sararak hala çalıştırabilirsiniz, örneğin:
const fp = require('fastify-plugin')
const routes = require('./lib/routes')
module.exports = fp(async function (app, opts) {
app.register(routes, {
prefix: '/v1',
})
}, {
name: 'my-routes'
})
Ön ekli eklentiler içindeki / rotasının işlenmesi
/
rotasının davranışı, önekin /
ile bitip bitmemesine bağlı olarak farklıdır. Örneğin,
bir önek /something/
düşünürsek, bir /
rotası eklemek bu sadece /something/
'i eşleyecektir.
Bir önek /something
alırsak, bir /
rotası eklemek, hem /something
hem de /something/
'i eşleştirecektir.
Bu davranışı değiştirmek için yukarıdaki prefixTrailingSlash
rota seçeneğine bakın.
Özel Log Seviyesi
Rotalarınızda farklı log seviyelerine ihtiyacınız olabilir; Fastify, bunu oldukça sade bir şekilde başarır.
Sadece logLevel
seçeneğini ya eklenti seçeneği ya da rota
seçeneği ile birlikte ihtiyacınız olan değeri
geçmeniz yeterlidir.
Eğer logLevel
'i eklenti seviyesinde ayarlarsanız,
setNotFoundHandler
ve
setErrorHandler
da etkilenir.
// server.js
const fastify = require('fastify')({ logger: true })
fastify.register(require('./routes/user'), { logLevel: 'warn' })
fastify.register(require('./routes/events'), { logLevel: 'debug' })
fastify.listen({ port: 3000 })
Ya da bunu doğrudan bir rotaya ulaştırabilirsiniz:
fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
reply.send({ hello: 'world' })
})
Özel log seviyesi yalnızca rotalara uygulanır ve küresel Fastify Logger'a değil,
fastify.log
ile erişilebilen log'a uygulanmaz.