@syntay/fastay 0.2.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # Fastay Documentation
1
+ # Fastay
2
2
 
3
3
  <p align="center">
4
- <img src="./fastay.png" width="200" />
5
- <br>
6
4
  <a href="https://www.npmjs.com/package/@syntay/fastay">
7
5
  <img src="https://img.shields.io/npm/v/@syntay/fastay.svg?style=flat-square" alt="npm version">
8
6
  </a>
@@ -17,1454 +15,35 @@
17
15
  </a>
18
16
  </p>
19
17
 
20
- Fastay is a modern backend framework built on Express.js, designed to create APIs quickly, predictably, and in a developer-friendly way.
21
-
22
- It is **TypeScript-first**, file-based, auto-discovers routes and middlewares, and provides a clean development experience.
18
+ Fastay is a modern backend framework built on Express.js, designed for fast, predictable, and developer-friendly API development. It is TypeScript-first, file-based, and automatically discovers routes and middlewares.
23
19
 
24
- ## Quick Navigation
20
+ The complete documentation is available at:
25
21
 
26
- - [Fastay Philosophy](#fastay-philosophy)
27
- - [Quick Start](#quick-start)
28
- - [Project Structure](#project-structure)
29
- - [Main Configuration](#main-configuration)
30
- - [Routing System](#routing-system)
31
- - [Middleware System](#middleware-system)
32
- - [Comparison with Other Frameworks](#comparison-with-other-frameworks)
33
-
34
- ## Fastay Philosophy
35
-
36
- ### The Art of Intentional Simplicity
37
-
38
- Fastay is born from an obsession with simplicity and speed, representing a minimalist approach to modern backend development. Our philosophy is based on principles that value efficiency without sacrificing power.
39
-
40
- ### Fundamental Principles
41
-
42
- #### 1. Less is More
43
- - We eliminate unnecessary layers that don't add real value
44
- - Focus on what's essential to build robust APIs
45
- - Zero architectural bureaucracy that drains time and energy
46
-
47
- #### 2. Freedom with Structure
48
- - We provide a solid foundation without imposing limitations
49
- - You maintain full control over how your project evolves
50
- - Flexibility to scale according to your specific needs
51
-
52
- #### 3. Fluid Development
53
- - Intuitive and frictionless development experience
54
- - Minimal configuration, maximum results
55
- - Focus on business logic, not complex configurations
56
-
57
- ### Who Fastay Was Created For
58
-
59
- **Ideal for:**
60
- - Developers who value simplicity and efficiency
61
- - Teams that need development speed
62
- - Projects requiring long-term maintainability
63
- - Those who prefer explicit code over complex magic
64
-
65
- **Perfect Use Cases:**
66
- - Small to medium-sized RESTful APIs
67
- - Quick prototypes and MVPs
68
- - Lightweight microservices
69
- - Projects where development speed is crucial
70
-
71
- ### The Perfect Balance
72
-
73
- Fastay finds the sweet spot between:
74
-
75
- **Express.js (too minimalist) ← FASTAY → NestJS (too structured)**
76
-
77
- **Developer freedom ← FASTAY → Smart conventions**
78
-
79
- **Total flexibility ← FASTAY → Maximum productivity**
80
-
81
- ### Technical Manifesto
82
-
83
- "We believe that frameworks should facilitate and not complicate. That complexity should be added by choice, not imposed by default. That developers deserve tools that respect their time and intelligence."
84
-
85
- Fastay is not just a framework - it's a statement of principles: that it's possible to have power without complexity, structure without rigidity, and conventions without dictatorship.
86
-
87
- [⬆ Back to Top](#fastay-documentation)
22
+ [https://fastay.syntay.site](https://fastay.syntay.site)
88
23
 
89
24
  ## Quick Start
90
25
 
91
- ### 1. Create a New Project
92
-
93
26
  ```bash
94
27
  npx fastay create-app my-app
95
- ```
96
-
97
- Example CLI interaction:
98
-
99
- ```
100
- Fastay — Create a modern backend project
101
- ✔ Use TypeScript? › Yes
102
- ✔ Choose an ORM: › None
103
- ```
104
-
105
- ### Navigate to the Project
106
-
107
- ```bash
108
28
  cd my-app
109
- ```
110
-
111
- ### Start Development Server
112
-
113
- ```bash
114
29
  npm run dev
115
30
  ```
116
31
 
117
- ### Watch Mode with Hot Reload
118
-
119
- ```bash
120
- npm run dev:watch
121
- ```
122
-
123
- [⬆ Back to Top](#fastay-documentation)
124
-
125
- ## Project Structure
126
-
127
- ```
128
- my-app/
129
-
130
- ├── dist/ # Compiled production code
131
- ├── src/
132
- │ ├── api/ # API routes (auto-loaded)
133
- │ │ ├── hello/
134
- │ │ │ └── route.ts
135
- │ │ ├── users/
136
- │ │ │ └── route.ts
137
- │ │ └── products/
138
- │ │ └── route.ts
139
- │ │
140
- │ ├── middlewares/ # Fastay middlewares
141
- │ │ ├── auth.ts
142
- │ │ ├── logger.ts
143
- │ │ └── middleware.ts
144
- │ │
145
- │ ├── services/ # Business logic (recommended)
146
- │ │ ├── user-service.ts
147
- │ │ └── product-service.ts
148
- │ │
149
- │ ├── utils/ # Helper functions
150
- │ │ └── formatters.ts
151
- │ │
152
- │ └── index.ts # Application entry point
153
-
154
- ├── fastay.config.json # Global framework configuration
155
- ├── package.json
156
- ├── tsconfig.json
157
- └── eslint.config.mjs
158
- ```
159
-
160
- ### Main Directories Description
161
-
162
- - **src/api** - Each folder represents a route group. Every route.ts is automatically registered
163
- - **src/middlewares** - Custom middlewares, automatically loaded
164
- - **src/services** - Keeps business logic separate from routes
165
- - **src/utils** - Helpers and utility functions
166
- - **src/index.ts** - Main application bootstrap
167
- - **dist/** - Compiled production code
168
- - **fastay.config.json** - Build and compiler configuration
169
-
170
- [⬆ Back to Top](#fastay-documentation)
171
-
172
- ## Main Configuration
173
-
174
- ### src/index.ts File
175
-
176
- ```typescript
177
- import { createApp } from '@syntay/fastay';
178
-
179
- const port = 5555;
180
-
181
- void (async () => {
182
- await createApp({
183
- apiDir: './src/api',
184
- baseRoute: '/api',
185
- port: port
186
- });
187
- })();
188
- ```
189
-
190
- ### createApp Configuration
191
-
192
- The createApp method is the heart of Fastay, responsible for initializing and configuring the entire application. It accepts a flexible configuration object that allows customization from routes to global middlewares.
193
-
194
- ### Configuration Parameters
195
-
196
- #### Basic Parameters
197
-
198
- ```typescript
199
- void (async () => {
200
- await createApp({
201
- // Server port (optional) - default: 5000
202
- port: 5000,
203
- // Routes directory (optional) - default: './src/api'
204
- apiDir: './src/api',
205
- // Base route (optional) - default: '/api'
206
- baseRoute: '/api',
207
- // Fastay middlewares (optional)
208
- middlewares: {
209
- '/api/hello': [home]
210
- }
211
- });
212
- })();
213
- ```
214
-
215
- #### Complete Practical Example
216
-
217
- ```typescript
218
- import { createApp } from '@syntay/fastay';
219
- import { home } from './middlewares/home';
220
-
221
- void (async () => {
222
- await createApp({
223
- port: 5000,
224
- apiDir: './src/api',
225
- baseRoute: '/api',
226
- middlewares: {
227
- '/api/hello': [home] // Middleware applied only to /api/hello route
228
- },
229
- expressOptions: {
230
- // Express configurations...
231
- }
232
- });
233
- })();
234
- ```
235
-
236
- ### Express Configurations (expressOptions)
237
-
238
- Since Fastay is built on Express, you can leverage all Express functionalities through the expressOptions object.
239
-
240
- #### Global Middlewares
241
-
242
- ```typescript
243
- expressOptions: {
244
- middlewares: [
245
- cors(),
246
- helmet(),
247
- (req, res, next) => {
248
- res.setHeader('X-Powered-By', 'Fastay.js');
249
- console.log("Global middleware executed");
250
- next();
251
- },
252
- ],
253
- }
254
- ```
255
-
256
- #### Body Parsers Configuration
257
-
258
- ```typescript
259
- expressOptions: {
260
- jsonOptions: {
261
- limit: '10mb', // Size limit for JSON
262
- strict: true // Only objects and arrays
263
- },
264
- urlencodedOptions: {
265
- extended: true, // Allows complex objects
266
- limit: '10mb' // Size limit
267
- },
268
- }
269
- ```
270
-
271
- #### Serve Static Files
272
-
273
- ```typescript
274
- expressOptions: {
275
- static: {
276
- path: "public", // Static files directory
277
- options: {
278
- maxAge: "1d", // 1 day cache
279
- etag: true // Enable ETag
280
- }
281
- },
282
- }
283
- ```
284
-
285
- #### Template Engine Configuration
286
-
287
- ```typescript
288
- expressOptions: {
289
- views: {
290
- engine: "pug", // Template engine (Pug, EJS, etc.)
291
- dir: "views" // Views directory
292
- },
293
- }
294
- ```
295
-
296
- #### Global Local Variables
297
-
298
- ```typescript
299
- expressOptions: {
300
- locals: {
301
- appName: "My Fastay App",
302
- version: "1.0.0",
303
- author: "Your Team"
304
- },
305
- }
306
- ```
307
-
308
- #### Reverse Proxy Configuration
309
-
310
- ```typescript
311
- expressOptions: {
312
- trustProxy: true, // Important for Nginx, Cloudflare, etc.
313
- }
314
- ```
315
-
316
- #### Custom Error Handler
317
-
318
- ```typescript
319
- expressOptions: {
320
- errorHandler: (err, req, res, next) => {
321
- console.error('Error captured:', err);
322
- if (err.statusCode) {
323
- res.status(err.statusCode).json({
324
- error: err.message,
325
- code: err.code
326
- });
327
- } else {
328
- res.status(500).json({
329
- error: 'Internal server error',
330
- code: 'INTERNAL_ERROR'
331
- });
332
- }
333
- },
334
- }
335
- ```
336
-
337
- ### CORS Configuration
338
-
339
- Fastay offers a simplified and powerful CORS configuration:
340
-
341
- #### Complete CORS Example
342
-
343
- ```typescript
344
- expressOptions: {
345
- enableCors: {
346
- // Allow requests from any origin (be careful in production)
347
- allowAnyOrigin: true,
348
- // Specific URLs that can send cookies
349
- cookieOrigins: [
350
- 'https://mysite.com',
351
- 'https://app.mysite.com',
352
- 'http://localhost:3000'
353
- ],
354
- // Enable cross-origin cookie sending
355
- credentials: true,
356
- // Allowed HTTP methods
357
- methods: 'GET,POST,PUT,DELETE,OPTIONS,PATCH,HEAD',
358
- // Allowed request headers
359
- headers: 'Content-Type, Authorization, X-Requested-With, X-Custom-Header',
360
- // Headers exposed to client
361
- exposedHeaders: 'X-Custom-Header, X-Total-Count',
362
- // Preflight request cache time (24 hours)
363
- maxAge: 86400,
364
- },
365
- }
366
- ```
367
-
368
- #### Secure Production Configuration
369
-
370
- ```typescript
371
- expressOptions: {
372
- enableCors: {
373
- allowAnyOrigin: false,
374
- cookieOrigins: [
375
- 'https://mydomain.com',
376
- 'https://api.mydomain.com'
377
- ],
378
- credentials: true,
379
- methods: 'GET,POST,PUT,DELETE',
380
- headers: 'Content-Type, Authorization',
381
- maxAge: 3600, // 1 hour
382
- },
383
- }
384
- ```
385
-
386
- #### Development Configuration
387
-
388
- ```typescript
389
- expressOptions: {
390
- enableCors: {
391
- allowAnyOrigin: true, // Allow any origin in development
392
- credentials: true,
393
- methods: 'GET,POST,PUT,DELETE,OPTIONS,PATCH',
394
- headers: '*', // Allow all headers
395
- maxAge: 86400,
396
- },
397
- }
398
- ```
399
-
400
- ### Complete Configuration Example
401
-
402
- ```typescript
403
- import { createApp } from '@syntay/fastay';
404
- import cors from 'cors';
405
- import helmet from 'helmet';
406
- import { authMiddleware } from './middlewares/auth';
407
- import { loggerMiddleware } from './middlewares/logger';
408
-
409
- void (async () => {
410
- await createApp({
411
- // Basic configurations
412
- port: process.env.PORT || 5000,
413
- apiDir: './src/api',
414
- baseRoute: '/api/v1',
415
-
416
- // Fastay middlewares
417
- middlewares: {
418
- '/api/v1/admin': [authMiddleware, loggerMiddleware],
419
- '/api/v1/users': [authMiddleware],
420
- },
421
-
422
- // Express configurations
423
- expressOptions: {
424
- // Global middlewares
425
- middlewares: [
426
- helmet(),
427
- (req, res, next) => {
428
- console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
429
- next();
430
- }
431
- ],
432
-
433
- // CORS configuration
434
- enableCors: {
435
- allowAnyOrigin: process.env.NODE_ENV === 'development',
436
- cookieOrigins: [
437
- 'https://mysite.com',
438
- 'https://app.mysite.com'
439
- ],
440
- credentials: true,
441
- methods: 'GET,POST,PUT,DELETE,OPTIONS',
442
- headers: 'Content-Type, Authorization, X-API-Key',
443
- maxAge: 86400,
444
- },
445
-
446
- // Body parsers
447
- jsonOptions: {
448
- limit: '10mb'
449
- },
450
- urlencodedOptions: {
451
- extended: true
452
- },
453
-
454
- // Static files
455
- static: {
456
- path: "public",
457
- options: {
458
- maxAge: 3600000
459
- }
460
- },
461
-
462
- // Template engine
463
- views: {
464
- engine: "ejs",
465
- dir: "src/views"
466
- },
467
-
468
- // Local variables
469
- locals: {
470
- appName: "My API",
471
- environment: process.env.NODE_ENV || 'development'
472
- },
473
-
474
- // Reverse proxy
475
- trustProxy: true,
476
-
477
- // Custom error handler
478
- errorHandler: (err, req, res, next) => {
479
- const isProduction = process.env.NODE_ENV === 'production';
480
- res.status(err.status || 500).json({
481
- error: isProduction ? 'Something went wrong' : err.message,
482
- ...(!isProduction && { stack: err.stack })
483
- });
484
- }
485
- }
486
- });
487
- })();
488
- ```
489
-
490
- ### Important Tips
491
-
492
- #### Middleware Order
493
-
494
- ```typescript
495
- // Order matters! Following the flow:
496
- expressOptions: {
497
- middlewares: [
498
- helmet(), // 1. Security first
499
- cors(), // 2. CORS before body parsers
500
- express.json(), // 3. Body parsers
501
- express.urlencoded(),
502
- logger, // 4. Logging
503
- auth // 5. Authentication
504
- ],
505
- }
506
- ```
507
-
508
- #### Environment-based Configuration
509
-
510
- ```typescript
511
- const isDevelopment = process.env.NODE_ENV === 'development';
512
-
513
- await createApp({
514
- port: process.env.PORT || 5000,
515
- expressOptions: {
516
- enableCors: {
517
- allowAnyOrigin: isDevelopment, // Only allowed in development
518
- credentials: !isDevelopment, // Cookies only in production
519
- },
520
- trustProxy: !isDevelopment, // Proxy only in production
521
- }
522
- });
523
- ```
524
-
525
- #### Specific vs Global Middlewares
526
-
527
- ```typescript
528
- await createApp({
529
- // Specific route middlewares (Fastay)
530
- middlewares: {
531
- '/api/admin': [adminAuth, adminLogger], // Only for /api/admin
532
- '/api/public': [rateLimit], // Only for /api/public
533
- },
534
- expressOptions: {
535
- // Global middlewares (Express)
536
- middlewares: [
537
- cors(), // For all routes
538
- helmet(), // For all routes
539
- ],
540
- }
541
- });
542
- ```
543
-
544
- ### Security Considerations
545
-
546
- - **CORS in Production**: Never use `allowAnyOrigin: true` in production
547
- - **Body Parser Limits**: Set reasonable limits to prevent attacks
548
- - **Helmet**: Always include Helmet for basic security
549
- - **Trust Proxy**: Configure correctly to avoid IP issues
550
-
551
- [⬆ Back to Top](#fastay-documentation)
552
-
553
- ## Routing System
554
-
555
- Fastay uses a file-based routing system that combines simplicity with power. Routes are self-discoverable and intuitively organized.
556
-
557
- ### API Folder Structure
558
-
559
- In Fastay.js, API routes are placed inside the directory defined in apiDir (default: './src/api'). Each subfolder represents an API endpoint.
560
-
561
- ```
562
- src/
563
- ├── api/
564
- │ ├── hello/
565
- │ │ └── route.ts # → /api/hello
566
- │ ├── users/
567
- │ │ └── route.ts # → /api/users
568
- │ └── products/
569
- │ └── route.ts # → /api/products
570
- ```
571
-
572
- ### Basic Route Definition
573
-
574
- #### Clean and Intuitive Syntax
575
-
576
- ```typescript
577
- import { Request } from '@syntay/fastay';
578
-
579
- // GET /api/hello
580
- export async function GET() {
581
- return "Hello World";
582
- }
583
-
584
- // POST /api/hello
585
- export async function POST(req: Request) {
586
- return { message: 'Hello World' };
587
- }
588
- ```
589
-
590
- **Routing System Characteristics:**
591
- - ✅ Each HTTP method is exported as a function
592
- - ✅ Automatically registered by Fastay
593
- - ✅ Fully typed and TypeScript compatible
594
- - ✅ Supports native Express middlewares
595
-
596
- ### Supported HTTP Methods
597
-
598
- You can handle all main HTTP methods in the same route file:
599
-
600
- ```typescript
601
- // api/users/route.ts
602
- import { Request } from '@syntay/fastay';
603
-
604
- // GET /api/users
605
- export async function GET() {
606
- const users = [
607
- { id: 1, name: 'John' },
608
- { id: 2, name: 'Mary' }
609
- ];
610
- return users;
611
- }
612
-
613
- // POST /api/users
614
- export async function POST(req: Request) {
615
- const userData = await req.body;
616
- // Save user to database
617
- return { message: 'User created successfully', user: userData };
618
- }
619
-
620
- // PUT /api/users
621
- export async function PUT(req: Request) {
622
- const userData = await req.body;
623
- // Update user
624
- return { message: 'User updated', user: userData };
625
- }
626
-
627
- // DELETE /api/users
628
- export async function DELETE(req: Request) {
629
- // Delete user
630
- return { message: 'User deleted' };
631
- }
632
-
633
- // PATCH /api/users
634
- export async function PATCH(req: Request) {
635
- const updates = await req.body;
636
- // Partial update
637
- return { message: 'User partially updated', updates };
638
- }
639
- ```
640
-
641
- ### Advanced Response System
642
-
643
- Fastay offers a flexible system for building HTTP responses with different content types.
644
-
645
- #### JSON Response (Default)
646
-
647
- ```typescript
648
- export async function GET() {
649
- return {
650
- success: true,
651
- data: { id: 1, name: 'John' }
652
- };
653
- }
654
- ```
655
-
656
- #### STRING Response
657
-
658
- ```typescript
659
- export async function GET() {
660
- return 'John Doe'
661
- }
662
- ```
663
-
664
- #### NUMBER Response
665
-
666
- ```typescript
667
- export async function GET() {
668
- return 1975
669
- }
670
- ```
671
-
672
- #### Response with Custom Status Code
673
-
674
- ```typescript
675
- export async function POST(req: Request) {
676
- const data = await req.body;
677
- return {
678
- status: 201, // Created
679
- body: {
680
- message: 'Resource created successfully',
681
- data
682
- }
683
- };
684
- }
685
- ```
686
-
687
- #### Response with Cookies
688
-
689
- ```typescript
690
- export async function POST(req: Request) {
691
- const token = 'jwt_token_here';
692
- const cookies = {
693
- user_token: {
694
- value: token,
695
- options: {
696
- httpOnly: true,
697
- secure: process.env.NODE_ENV === 'production',
698
- path: '/',
699
- sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
700
- domain: process.env.NODE_ENV === 'production' ? 'yoursite.com' : 'localhost',
701
- maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
702
- },
703
- },
704
- };
705
-
706
- return {
707
- cookies,
708
- status: 200,
709
- body: {
710
- message: "User registered successfully"
711
- }
712
- };
713
- }
714
- ```
715
-
716
- #### Response with Custom Headers
717
-
718
- ```typescript
719
- export async function GET() {
720
- return {
721
- headers: {
722
- 'Content-Type': 'application/json',
723
- 'X-Custom-Header': 'custom-value',
724
- 'Cache-Control': 'no-cache'
725
- },
726
- body: {
727
- data: 'content'
728
- }
729
- };
730
- }
731
- ```
732
-
733
- #### Redirection
734
-
735
- ```typescript
736
- export async function GET() {
737
- // Temporary redirection (302)
738
- return {
739
- redirect: '/new-route',
740
- status: 302
741
- };
742
- }
743
-
744
- export async function POST() {
745
- // Permanent redirection (301)
746
- return {
747
- redirect: 'https://example.com',
748
- status: 301
749
- };
750
- }
751
- ```
752
-
753
- #### File Download
754
-
755
- ```typescript
756
- export async function GET() {
757
- return {
758
- file: {
759
- path: '/path/to/report.pdf',
760
- downloadName: 'monthly-report.pdf'
761
- }
762
- };
763
- }
764
- ```
765
-
766
- #### Data Stream
767
-
768
- ```typescript
769
- import fs from 'fs';
770
-
771
- export async function GET() {
772
- return {
773
- stream: fs.createReadStream('/videos/movie.mp4'),
774
- headers: {
775
- 'Content-Type': 'video/mp4'
776
- }
777
- };
778
- }
779
- ```
780
-
781
- #### Raw Response (Buffer/String)
32
+ ## Why Fastay?
782
33
 
783
- ```typescript
784
- export async function GET() {
785
- return {
786
- raw: Buffer.from('Hello World in plain text'),
787
- headers: {
788
- 'Content-Type': 'text/plain'
789
- }
790
- };
791
- }
792
- ```
793
-
794
- ### Dynamic Routes
795
-
796
- #### URL Parameters
797
-
798
- ```typescript
799
- // api/users/[id]/route.ts
800
- import { Request } from '@syntay/fastay';
801
-
802
- export async function GET(req: Request) {
803
- const { id } = req.params;
804
- // Find user by ID
805
- return {
806
- message: `User details with ID: ${id}`,
807
- user: { id, name: `User ${id}` }
808
- };
809
- }
810
- ```
811
-
812
- **Access:** `GET /api/users/123` → `{ id: '123' }`
813
-
814
- #### Query Parameters
815
-
816
- ```typescript
817
- // api/users/route.ts
818
- import { Request } from '@syntay/fastay';
819
-
820
- interface UserQuery {
821
- name?: string;
822
- email?: string;
823
- page?: number;
824
- }
825
-
826
- export async function GET(req: Request) {
827
- const query: UserQuery = req.query;
828
- const { name, email, page = 1 } = query;
829
-
830
- // Find users with filters
831
- return {
832
- users: [
833
- { id: 1, name, email },
834
- { id: 2, name: 'Mary', email: 'mary@email.com' }
835
- ],
836
- pagination: {
837
- page,
838
- totalPages: 5
839
- }
840
- };
841
- }
842
- ```
843
-
844
- **Access:** `GET /api/users?name=John&email=john@email.com&page=2`
845
-
846
- #### Combining Parameters and Query
847
-
848
- ```typescript
849
- // api/users/[id]/posts/route.ts
850
- import { Request } from '@syntay/fastay';
851
-
852
- export async function GET(req: Request) {
853
- const { id } = req.params; // User ID
854
- const { category, limit = 10 } = req.query; // Filters
855
-
856
- return {
857
- userId: id,
858
- posts: [
859
- { id: 1, title: 'Post 1', category },
860
- { id: 2, title: 'Post 2', category }
861
- ],
862
- filters: { category, limit }
863
- };
864
- }
865
- ```
866
-
867
- ### Working with FormData
868
-
869
- #### File Uploads and Forms
870
-
871
- ```typescript
872
- // api/upload/route.ts
873
- import { Request } from '@syntay/fastay';
874
-
875
- export async function POST(req: Request) {
876
- const formData = await req.formData();
877
- const id = formData.get('id') as string;
878
- const name = formData.get('name') as string;
879
- const image = formData.get('image') as File;
880
-
881
- // Process image upload
882
- console.log('File received:', image.name, image.size);
883
-
884
- return {
885
- message: 'Upload completed successfully',
886
- data: { id, name, fileName: image.name }
887
- };
888
- }
889
- ```
890
-
891
- ### Working with Cookies
892
-
893
- #### Reading Cookies
894
-
895
- ```typescript
896
- export async function GET(req: Request) {
897
- // Check if cookie exists
898
- if (req.cookies.has('user_token')) {
899
- // Get cookie value
900
- const token = req.cookies.get('user_token');
901
- return {
902
- authenticated: true,
903
- user: { token }
904
- };
905
- }
906
-
907
- return { authenticated: false };
908
- }
909
- ```
910
-
911
- #### Available Cookie Methods
912
-
913
- ```typescript
914
- export async function GET(req: Request) {
915
- // Check existence
916
- const hasToken = req.cookies.has('user_token');
917
- // Get value
918
- const token = req.cookies.get('user_token');
919
- // Get all cookies
920
- const allCookies = req.cookies.all();
921
-
922
- return {
923
- cookieInfo: {
924
- hasToken,
925
- token,
926
- allCookies
927
- }
928
- };
929
- }
930
- ```
931
-
932
- ### Error Handling
933
-
934
- #### Try/Catch Block
935
-
936
- ```typescript
937
- export async function GET() {
938
- try {
939
- const data = await fetchExternalData();
940
- return { data };
941
- } catch (error) {
942
- return {
943
- status: 500,
944
- body: {
945
- error: 'Internal server error',
946
- message: error.message
947
- }
948
- };
949
- }
950
- }
951
- ```
952
-
953
- #### Errors with Specific Status Codes
954
-
955
- ```typescript
956
- export async function GET(req: Request) {
957
- const { id } = req.params;
958
- const user = await findUserById(id);
959
-
960
- if (!user) {
961
- return {
962
- status: 404,
963
- body: { error: 'User not found' }
964
- };
965
- }
966
-
967
- if (!user.active) {
968
- return {
969
- status: 403,
970
- body: { error: 'User inactive' }
971
- };
972
- }
973
-
974
- return { user };
975
- }
976
- ```
977
-
978
- #### Data Validation
979
-
980
- ```typescript
981
- export async function POST(req: Request) {
982
- const userData = await req.body;
983
-
984
- // Simple validation
985
- if (!userData.name || !userData.email) {
986
- return {
987
- status: 400,
988
- body: {
989
- error: 'Invalid data',
990
- required: ['name', 'email']
991
- }
992
- };
993
- }
994
-
995
- // Process valid data
996
- return {
997
- status: 201,
998
- body: {
999
- message: 'User created',
1000
- user: userData
1001
- }
1002
- };
1003
- }
1004
- ```
1005
-
1006
- ### Complete Practical Examples
1007
-
1008
- #### Complete Blog API
1009
-
1010
- ```typescript
1011
- // api/posts/route.ts
1012
- import { Request } from '@syntay/fastay';
1013
-
1014
- // GET /api/posts - List posts with pagination
1015
- export async function GET(req: Request) {
1016
- const { page = 1, limit = 10, category } = req.query;
1017
- const posts = await findPosts({
1018
- page: parseInt(page),
1019
- limit: parseInt(limit),
1020
- category
1021
- });
1022
-
1023
- return {
1024
- posts,
1025
- pagination: {
1026
- page,
1027
- limit,
1028
- total: posts.length
1029
- }
1030
- };
1031
- }
1032
-
1033
- // POST /api/posts - Create new post
1034
- export async function POST(req: Request) {
1035
- const postData = await req.body;
1036
-
1037
- // Validation
1038
- if (!postData.title || !postData.content) {
1039
- return {
1040
- status: 400,
1041
- body: { error: 'Title and content are required' }
1042
- };
1043
- }
1044
-
1045
- const newPost = await createPost(postData);
1046
- return {
1047
- status: 201,
1048
- body: {
1049
- message: 'Post created successfully',
1050
- post: newPost
1051
- }
1052
- };
1053
- }
1054
- ```
1055
-
1056
- #### Authentication API
1057
-
1058
- ```typescript
1059
- // api/auth/login/route.ts
1060
- import { Request } from '@syntay/fastay';
1061
-
1062
- export async function POST(req: Request) {
1063
- const { email, password } = await req.body;
1064
-
1065
- // Verify credentials
1066
- const user = await verifyCredentials(email, password);
1067
- if (!user) {
1068
- return {
1069
- status: 401,
1070
- body: { error: 'Invalid credentials' }
1071
- };
1072
- }
1073
-
1074
- // Generate token
1075
- const token = generateJWTToken(user);
1076
-
1077
- const cookies = {
1078
- auth_token: {
1079
- value: token,
1080
- options: {
1081
- httpOnly: true,
1082
- secure: process.env.NODE_ENV === 'production',
1083
- maxAge: 24 * 60 * 60 * 1000, // 24 hours
1084
- path: '/'
1085
- }
1086
- }
1087
- };
1088
-
1089
- return {
1090
- cookies,
1091
- body: {
1092
- message: 'Login successful',
1093
- user: {
1094
- id: user.id,
1095
- name: user.name
1096
- }
1097
- }
1098
- };
1099
- }
1100
- ```
1101
-
1102
- ### Best Practices Tips
1103
-
1104
- #### Route Organization
1105
-
1106
- ```
1107
- src/api/
1108
- ├── users/
1109
- │ ├── route.ts # Basic operations
1110
- │ ├── [id]/
1111
- │ │ └── route.ts # Operations by ID
1112
- │ └── auth/
1113
- │ └── route.ts # Authentication
1114
- ├── posts/
1115
- │ ├── route.ts
1116
- │ └── [id]/
1117
- │ └── comments/
1118
- │ └── route.ts # Post comments
1119
- ```
1120
-
1121
- #### Consistent Validation
1122
-
1123
- ```typescript
1124
- // utils/validation.ts
1125
- export function validateUser(data: any) {
1126
- const errors = [];
1127
- if (!data.name) errors.push('Name is required');
1128
- if (!data.email) errors.push('Email is required');
1129
- if (!validateEmail(data.email)) errors.push('Invalid email');
1130
- return errors;
1131
- }
1132
-
1133
- // api/users/route.ts
1134
- export async function POST(req: Request) {
1135
- const userData = await req.body;
1136
- const errors = validateUser(userData);
1137
-
1138
- if (errors.length > 0) {
1139
- return {
1140
- status: 400,
1141
- body: { errors: errors }
1142
- };
1143
- }
1144
-
1145
- // Process valid data...
1146
- }
1147
- ```
1148
-
1149
- #### Standardized Responses
1150
-
1151
- ```typescript
1152
- // utils/response.ts
1153
- export function success(data: any, message = 'Success') {
1154
- return {
1155
- status: 'success',
1156
- message,
1157
- data
1158
- };
1159
- }
1160
-
1161
- export function error(message: string, code = 'ERROR') {
1162
- return {
1163
- status: 'error',
1164
- message,
1165
- code
1166
- };
1167
- }
1168
-
1169
- // Usage in routes
1170
- export async function GET() {
1171
- try {
1172
- const users = await findUsers();
1173
- return success(users, 'Users listed successfully');
1174
- } catch (err) {
1175
- return error('Error fetching users');
1176
- }
1177
- }
1178
- ```
1179
-
1180
- [⬆ Back to Top](#fastay-documentation)
1181
-
1182
- ## Middleware System
1183
-
1184
- ### Auto-loaded Middlewares
1185
-
1186
- ```typescript
1187
- import { Request, Response, Next } from '@syntay/fastay';
1188
-
1189
- export async function auth(req: Request, _res: Response, next: Next) {
1190
- // Authentication logic
1191
- next();
1192
- }
1193
- ```
1194
-
1195
- ### Middleware Configuration in Fastay.js
1196
-
1197
- In Fastay.js, middlewares are used to intercept and process requests before they reach the defined routes. They work as "intermediate functions" that can perform actions like authentication, data validation, logging, among others, and are executed in the defined sequence until the request reaches the final route.
1198
-
1199
- #### Execution Flow
1200
-
1201
- ```
1202
- Request → Middleware 1 → Middleware 2 → ... → Final Route → Response
1203
- ```
1204
-
1205
- ### Basic Structure
1206
-
1207
- #### Recommended File Structure
1208
-
1209
- ```
1210
- src/
1211
- ├── middlewares/
1212
- │ ├── auth.ts # Authentication middleware
1213
- │ ├── validation.ts # Validation middleware
1214
- │ ├── logger.ts # Logging middleware
1215
- │ └── middleware.ts # Main configuration
1216
- ```
1217
-
1218
- ### Configuration
1219
-
1220
- #### createMiddleware Method
1221
-
1222
- The createMiddleware method allows associating middlewares with specific routes:
1223
-
1224
- ```typescript
1225
- export const middleware = createMiddleware({
1226
- // Syntax: [route]: [array-of-middlewares]
1227
- '/api/specific-route': [middleware1, middleware2],
1228
- // Multiple routes
1229
- '/api/users': [auth],
1230
- '/api/posts': [auth, logger],
1231
- '/api/public': [logger],
1232
- });
1233
- ```
1234
-
1235
- ### Defining Middlewares in Fastay.js
1236
-
1237
- Middlewares in Fastay.js are defined by convention in a directory called middlewares. Inside this directory, you create a middleware.ts (or middleware.js) file, where you can associate each middleware with a specific route.
1238
-
1239
- #### middleware.ts File Example
1240
-
1241
- The middleware.ts file is responsible for loading and applying middlewares to specific routes.
1242
-
1243
- ```typescript
1244
- // src/middlewares/middleware.ts
1245
- import { createMiddleware } from '@syntay/fastay';
1246
- import { user } from './user';
1247
- import { home } from './home';
1248
-
1249
- // Here, you define the routes and middlewares that will be executed before each route
1250
- export const middleware = createMiddleware({
1251
- '/api/users': [user], // User middleware will be applied to /api/users route
1252
- '/api/hello': [home], // Home middleware will be applied to /api/hello route
1253
- });
1254
- ```
1255
-
1256
- - **Route (/api/users)**: The specific route where the middleware will be executed. This allows you to associate middlewares with specific routes.
1257
- - **Array of Middlewares ([user])**: An array of middlewares that will be executed before the route execution. There can be multiple middlewares in an array, and they will be executed in the order they are defined.
1258
-
1259
- ### Middleware Structure
1260
-
1261
- A middleware in Fastay.js is basically an asynchronous function that receives three parameters: request, response, and next. The next() is used to indicate that the middleware has finished its execution and that the request can continue to the next middleware or to the target route.
1262
-
1263
- #### user.ts Middleware Example
1264
-
1265
- ```typescript
1266
- // src/middlewares/user.ts
1267
- import { Next, Request, Response } from '@syntay/fastay';
1268
-
1269
- export async function user(request: Request, _response: Response, next: Next) {
1270
- console.log('User middleware executed');
1271
- // Middleware logic, such as authentication or validation
1272
- // Call the next middleware or route
1273
- next();
1274
- }
1275
- ```
1276
-
1277
- - **request**: The request object containing the request data.
1278
- - **response**: The response object, which allows manipulating the response before sending it to the client.
1279
- - **next()**: Calls the next function in the middleware chain or the target route. If you don't call next(), the request will be "stuck" and won't proceed to the next middleware or route.
1280
-
1281
- ### Middleware Behavior
1282
-
1283
- - **Sequential Execution**: Middlewares are executed sequentially. If you have multiple middlewares for the same route, they will be called in the order they are defined in the array.
1284
- - **Execution Interruption**: If any middleware doesn't call next() or returns a response, the execution will be interrupted and the request won't proceed to the next middleware or route.
1285
-
1286
- #### Execution Order
1287
-
1288
- ```typescript
1289
- export const middleware = createMiddleware({
1290
- '/api/protected': [
1291
- middleware1, // Executed first
1292
- middleware2, // Executed second
1293
- middleware3 // Executed third
1294
- ],
1295
- });
1296
- ```
1297
-
1298
- #### Validation Middleware Example
1299
-
1300
- ```typescript
1301
- // src/middlewares/validate.ts
1302
- import { Next, Request, Response } from '@syntay/fastay';
1303
-
1304
- export async function validate(request: Request, response: Response, next: Next) {
1305
- if (!request.headers['authorization']) {
1306
- response.status(400).json({ error: 'Missing authorization header' });
1307
- } else {
1308
- next(); // If validation passes, call next middleware or route
1309
- }
1310
- }
1311
- ```
1312
-
1313
- ### Caution with Heavy Processing
1314
-
1315
- It's important to remember that middlewares should not be used for heavy tasks, such as processing large file uploads, database interactions, or complex calculations. The purpose of middlewares is to be lightweight and fast, with tasks like authentication, validation, or logging, and not for high computational cost operations.
1316
-
1317
- ### Complete Middleware Example in Fastay.js
34
+ - File-based routing with auto-discovery
35
+ - Clean separation between routes and middlewares
36
+ - Minimal configuration, maximum productivity
37
+ - Ideal for REST APIs, microservices, and MVPs
1318
38
 
1319
- #### Directory Structure
39
+ ## Contributing
1320
40
 
1321
- ```
1322
- src/
1323
- middlewares/
1324
- home.ts
1325
- user.ts
1326
- middleware.ts
1327
- ```
1328
-
1329
- #### middleware.ts
1330
-
1331
- ```typescript
1332
- import { createMiddleware } from '@syntay/fastay';
1333
- import { user } from './user';
1334
- import { home } from './home';
1335
-
1336
- export const middleware = createMiddleware({
1337
- '/api/users': [user], // User middleware for /api/users
1338
- '/api/hello': [home], // Home middleware for /api/hello
1339
- });
1340
- ```
1341
-
1342
- #### user.ts (Authentication Middleware)
1343
-
1344
- ```typescript
1345
- import { Next, Request, Response } from '@syntay/fastay';
1346
-
1347
- export async function user(request: Request, _response: Response, next: Next) {
1348
- console.log('User middleware executed');
1349
-
1350
- // Simulated authentication token validation
1351
- if (!request.headers['authorization']) {
1352
- return _response.status(401).json({ error: 'Unauthorized' });
1353
- }
1354
-
1355
- // If everything is correct, call next middleware or route
1356
- next();
1357
- }
1358
- ```
1359
-
1360
- #### home.ts (Logging Middleware)
1361
-
1362
- ```typescript
1363
- import { Next, Request, Response } from '@syntay/fastay';
1364
-
1365
- export async function home(request: Request, _response: Response, next: Next) {
1366
- console.log('Home middleware executed');
1367
- // Add logging logic here
1368
- // Call next middleware or route
1369
- next();
1370
- }
1371
- ```
1372
-
1373
- This example provides a complete explanation of how to configure and use middlewares in Fastay.js, with ready-to-copy code examples to apply in your project.
1374
-
1375
- [⬆ Back to Top](#fastay-documentation)
1376
-
1377
- ## Comparison with Other Frameworks
1378
-
1379
- ### Pure Express.js
1380
-
1381
- ```typescript
1382
- import express from 'express';
1383
- const app = express();
1384
-
1385
- // GET
1386
- app.get('/api/hello', (req, res) => {
1387
- res.json({ message: 'Hello World' });
1388
- });
1389
-
1390
- // POST
1391
- app.post('/api/hello', (req, res) => {
1392
- res.json({ message: 'Hello POST World' });
1393
- });
1394
-
1395
- app.listen(5000, () => console.log('Server running on port 5000'));
1396
- ```
1397
-
1398
- **Disadvantages of pure Express:**
1399
- - ❌ Manual registration of each route
1400
- - ❌ Middleware and routes mixed together
1401
- - ❌ Complicated scalability in large projects
1402
-
1403
- ### NestJS
1404
-
1405
- ```typescript
1406
- import { Controller, Get, Post, Body } from '@nestjs/common';
1407
-
1408
- @Controller('api/hello')
1409
- export class HelloController {
1410
- @Get()
1411
- getHello() {
1412
- return { message: 'Hello World' };
1413
- }
1414
-
1415
- @Post()
1416
- postHello(@Body() body: any) {
1417
- return { message: 'Hello POST World', body };
1418
- }
1419
- }
1420
- ```
1421
-
1422
- **NestJS Characteristics:**
1423
- - ✅ Based on decorators and classes
1424
- - ✅ Module organization
1425
- - ✅ Type-safe and TypeScript
1426
- - ⚠️ Learning curve with decorators and DI
1427
-
1428
- ### Fastay.js
1429
-
1430
- ```typescript
1431
- import { Request } from '@syntay/fastay';
1432
-
1433
- // GET /api/hello
1434
- export async function GET() {
1435
- return { message: 'Hello World' };
1436
- }
1437
-
1438
- // POST /api/hello
1439
- export async function POST(req: Request) {
1440
- return { message: 'Hello POST World' };
1441
- }
1442
- ```
1443
-
1444
- **Fastay Advantages:**
1445
- - ✅ File-based - each HTTP method is exported
1446
- - ✅ Auto-discovered routes - no manual registration
1447
- - ✅ Separate and organized middleware
1448
- - ✅ Type-safe, clean and simple
1449
-
1450
- ### Request Flow
1451
-
1452
- ```
1453
- Client → Fastay Route → Middleware → Route Handler → Service → Response
1454
- ```
1455
-
1456
- ## Contribution
1457
-
1458
- Contributions are welcome! Follow the steps:
1459
-
1460
- 1. Fork the project
41
+ 1. Fork the repository
1461
42
  2. Create a branch (`git checkout -b my-feature`)
1462
- 3. Commit your changes (`git commit -am 'Add new feature'`)
1463
- 4. Push to the branch (`git push origin my-feature`)
43
+ 3. Commit your changes (`git commit -m "Add feature"`)
44
+ 4. Push to your branch
1464
45
  5. Open a Pull Request
1465
46
 
1466
47
  ## License
1467
48
 
1468
49
  MIT © Syntay Team
1469
-
1470
- [⬆ Back to Top](#fastay-documentation)