HTTP Requests
The base FormRequest
instance provides a variety of methods for examining the incoming HTTP request. FormRequest
is built on top of FastifyRequest
, this means you can access FastifyRequest
methods and properties from the FormRequest
instance.
You may also use
Request
, an alias ofFormRequest
.
Accessing The Request
Formidable loads requests to route actions as first parameters by default:
- Imba
- TypeScript
import { Request } from '@formidablejs/framework'
import { Controller } from './Controller'
export class TaskController < Controller
def store request\Request
const description\string = request.get('description')
import { Request } from '@formidablejs/framework'
import { Controller } from './Controller'
export class TaskController extends Controller {
store(request: Request): void {
const description: string = request.get('description')
}
}
The request loaded by default, is the standard FormRequest
class provided by the Formidable Framework.
To use a different FormRequest
, you may use the @use
decorator:
- Imba
- TypeScript
import { @use } from '@formidablejs/framework'
import { StoreTaskRequest } from '../Requests/StoreTaskRequest'
import { Controller } from './Controller'
export class TaskController < Controller
@use(StoreTaskRequest)
def store request\StoreTaskRequest
const description\string = request.get('description')
import { use } from '@formidablejs/ts-ports'
import { StoreTaskRequest } from '../Requests/StoreTaskRequest'
import { Controller } from './Controller'
export class TaskController extends Controller {
@use(StoreTaskRequest)
store(request: StoreTaskRequest): void {
const description: string = request.get('description')
}
}
This, will use the StoreTaskRequest
request instead.
Request Host & Origin
Retrieving The Request Host
The getHost
method returns the request's host:
- Imba
- TypeScript
const host\string = request.getHost!
const host: string = request.getHost()
Retrieving The Request Origin
The getOrigin
method returns the request's origin:
- Imba
- TypeScript
const origin\string = request.getOrigin!
const origin: string = request.getOrigin()
You may also use the getFullOrigin
method to retrieve the full origin including the protocol:
- Imba
- TypeScript
const fullOrigin\string = request.getFullOrigin!
const fullOrigin: string = request.getFullOrigin()
Retrieving The Request Origin protocol
The getOriginProtocol
method returns the request's protocol:
- Imba
- TypeScript
const protocol\string = request.getOriginProtocol!
const protocol: string = request.getOriginProtocol()
Request Path, Param & Method
Retrieving The Request Url
The url
method returns the request's path. So, if the incoming request is targeted at http://example.com/tasks/store, the url
method will return tasks/store
:
- Imba
- TypeScript
const uri = request.url!
const uri = request.url()
Inspecting The Request Url / Path / Route
The isUrl
method allows you to verify that the incoming request path matches a given url:
- Imba
- TypeScript
if request.isUrl 'tasks/store'
# do somthing
if (request.isUrl('tasks/store')) {
// do somthing
}
You may also use
pathIs
. You may use the*
character as a wildcard when utilizing this method:
- Imba
- TypeScript
if request.pathIs 'tasks/*'
# do somthing
if (request.pathIs('tasks/*')) {
// do somthing
}
Using the isRoute
method, you may determine if the incoming request has matched a named route. You may use the *
character as a wildcard when utilizing this method:
- Imba
- TypeScript
if request.isRoute 'tasks.*'
# do something
if (request.isRoute('tasks.*')) {
// do something
}
Retrieving The Request URL
To retrieve the full URL for the incoming request you may use the url
, urlWithoutQuery
or fullUrl
methods. The url
method will return the path with the query string, the urlWithoutQuery
method will return the URL without the query string, and the fullUrl
method will return the host, the path and the query string:
- Imba
- TypeScript
const url\string = request.url!
const urlWithoutQueryString\string = request.urlWithoutQuery!
const fullUrl\string = request.fullUrl!
const url: string = request.url()
const urlWithoutQueryString: string = request.urlWithoutQuery()
const fullUrl: string = request.fullUrl()
Retrieving Route Parameters
To retrieve a route parameter from the incoming request you may use the param
method. The param
method accepts a parameter name:
- Imba
- TypeScript
const slug\string|null = request.param('slug')
const slug: string|null = request.param('slug')
To retrieve all route parameters, you may use the params
method:
- Imba
- TypeScript
const params\object = request.params!
const params: object = request.params()
Retrieving The Request Method
The method
method will return the HTTP verb for the request. You may use the isMethod
method to verify that the HTTP verb matches a given string:
- Imba
- TypeScript
const method\string = request.method!
if request.isMethod 'POST'
# do something
const method: string = request.method()
if (request.isMethod('POST')) {
// do something
}
Request Headers
You may retrieve a request header from the FormRequest
instance using the header method. If the header is not present on the request, null
will be returned. However, the header
method accepts an optional second argument that will be returned if the header is not present on the request:
- Imba
- TypeScript
const value\string|null = request.header('header-name')
const value\string = request.header('header-name', 'default')
const value: string|null = request.header('header-name')
const value: string = request.header('header-name', 'default')
The hasHeader
method may be used to determine if the request contains a given header:
- Imba
- TypeScript
if request.hasHeader 'header-name'
# do something
if (request.hasHeader('header-name')) {
// do something
}
For convenience, the bearerToken
method may be used to retrieve a bearer token from the Authorization
header. If no such header is present, an empty string will be returned:
- Imba
- TypeScript
const token\string|null = request.bearerToken!
const token: string|null = request.bearerToken()
Request IP Address
The ip
method may be used to retrieve the IP address of the client that made the request to your application:
- Imba
- TypeScript
const ipAddress\string = request.ip!
const ipAddress: string = request.ip()
Input
Retrieving Input
Retrieving All Input Data
You may retrieve all of the incoming request's input data as an object
using the all
method:
- Imba
- TypeScript
const input\object = request.all!
const input: object = request.all()
Retrieving An Input Value
Using a few simple methods, you may access all of the user input from your FormRequest
instance without worrying about which HTTP verb was used for the request. Regardless of the HTTP verb, the input method may be used to retrieve user input:
- Imba
- TypeScript
const name\string|null = request.input('name')
const name: string|null = request.input('name')
You may pass a default value as the second argument to the input
method. This value will be returned if the requested input value is not present on the request:
- Imba
- TypeScript
const name\string = request.input('name', 'Luna')
const name: string = request.input('name', 'Luna')
You may call the input method without any arguments in order to retrieve all of the input values as an object:
- Imba
- TypeScript
const input\object = request.input!
const input: object = request.input()
Retrieving Input From The Query String
While the input
method retrieves values from the entire request payload (including the query string), the query
method will only retrieve values from the query string:
- Imba
- TypeScript
const name\string|null = request.name('name')
const name: string|null = request.name('name')
If the requested query string value data is not present, the second argument to this method will be returned:
- Imba
- TypeScript
const name\string = request.name('name', 'Luna')
const name: string = request.name('name', 'Luna')
You may call the query
method without any arguments in order to retrieve all of the query string values as an object
:
- Imba
- TypeScript
const query\object = request.query!
const query: object = request.query()
Retrieving A Portion Of The Input Data
If you need to retrieve a subset of the input
data, you may use the only
method. This method accepts an array:
- Imba
- TypeScript
const input\object = request.only(['email', 'password'])
const input: object = request.only(['email', 'password'])
Retrieving Input From The Input Data And The Query String
If you are expecting data from both the query string data and input data, you may use the get
method. Note, input data takes first preference over the query string:
- Imba
- TypeScript
const name\string|null = request.get('name')
const name: string|null = request.get('name')
If the requested query string value data or input data is not present, the second argument to this method will be returned:
- Imba
- TypeScript
const name\string = request.get('name', 'Luna')
const name: string = request.get('name', 'Luna')
Determining If Input Is Present
You may use the has
method to determine if a value is present on the request. The has method returns true
if the value is present on the request:
- Imba
- TypeScript
if request.has 'name'
# do something
if(request.has('name')) {
// do something
}
File Uploads
Formidable provides an easy way to work with file uploads. You may access uploaded files using the file
method on the FormRequest
instance. The file
method returns an instance of FileCollection
:
- Imba
- TypeScript
const files = request.file('avatar')
const files = request.file('avatar')
File Methods
Retrieving A File
The file
method returns an instance of FileCollection
. You may use the first
method to retrieve the first file in the collection:
- Imba
- TypeScript
const file = request.file('avatar').first()
const file = request.file('avatar').first()
Retrieving All Files
The all
method may be used to retrieve all of the files in the collection:
- Imba
- TypeScript
const files = request.file('avatar').all()
const files = request.file('avatar').all()
You may also use the get
method to retrieve all of the files in the collection:
- Imba
- TypeScript
const files = request.file('avatar').get()
const files = request.file('avatar').get()
Retrieving First File
The first
method may be used to retrieve the first file in the collection:
- Imba
- TypeScript
const file = request.file('avatar').first()
const file = request.file('avatar').first()
Retrieving Last File
The last
method may be used to retrieve the last file in the collection:
- Imba
- TypeScript
const file = request.file('avatar').last()
const file = request.file('avatar').last()
Retrieving Files By Filter
You may use the filter
method to retrieve files that match a given filter. The filter
method accepts a callback function that will be used to filter the files:
- Imba
- TypeScript
const files = request.file('avatar').filter do(file)
file.size > 1000
const files = request.file('avatar').filter(file => file.size > 1000)
You may also use the where
method to retrieve files that match a given key-value pair:
- Imba
- TypeScript
const files = request.file('avatar').where('mimetype', 'image/png').get()
const files = request.file('avatar').where('mimetype', 'image/png').get()
Mapping Through Files
You may use the map
method to iterate over the files in the collection. The map
method accepts a callback function that will be used to map over the files:
- Imba
- TypeScript
const files = request.file('avatar').map do(file)
# do something
const files = request.file('avatar').map(file => {
// do something
})
Iterating Over Files
You may use the each
method to iterate over the files in the collection. The each
method accepts a callback function that will be used to iterate over the files:
- Imba
- TypeScript
request.file('avatar').each do(file)
# do something
request.file('avatar').each(file => {
// do something
})
Counting Files
You may use the count
method to count the number of files in the collection:
- Imba
- TypeScript
const count = request.file('avatar').count()
const count = request.file('avatar').count()
Determining If Files Are Present
You may use the hasFiles
method to determine if files are present in the collection. The hasFiles
method returns true
if files are present in the collection:
- Imba
- TypeScript
if request.file('avatar').hasFiles()
# do something
if (request.file('avatar').hasFiles()) {
// do something
}
You may also use the hasFile
method on the Request
or FormRequest
instance to determine if a file is present on the request. The hasFile
method returns true
if the file is present on the request:
- Imba
- TypeScript
if request.hasFile('avatar')
# do something
if (request.hasFile('avatar')) {
// do something
}
Working With Files
Storing Files
You may use the move
method to move an uploaded file to a new location. The move
method accepts two arguments: the destination directory and overwriting the file if it already exists:
- Imba
- TypeScript
const avatar = request.file('avatar').first()
avatar.move("storage/avatars/{avatar.name}", true)
const avatar = request.file('avatar').first()
avatar.move(`storage/avatars/${avatar.name}`, true)
Retrieving File Information
You may retrieve information about an uploaded file using the following getters:
Property | Description |
---|---|
name | The name of the file. |
filename | The name of the file. |
encoding | The encoding of the file. |
mime | The MIME type of the file. |
mimetype | The MIME type of the file. |
type | The MIME type of the file. |
path | The path to the file. |
extension | The extension of the file. |
ext | The extension of the file. |
size | The size of the file in MB. |
For example, to retrieve the extension of an uploaded file, you may use the extension
getter:
- Imba
- TypeScript
const avatar = request.file('avatar').first()
const extension = avatar.extension
const avatar = request.file('avatar').first()
const extension = avatar.extension
Validating File Uploads
When working with file uploads, you may use the file
rule to validate that the uploaded file is a file. The file
rule may be used to validate that the uploaded file is an image, audio, video, or PDF file. The file
rule may be used to validate that the uploaded file is an image file:
- Imba
- TypeScript
import { Request } from '@formidablejs/framework'
export class StorePersonRequest < Request
def rules
avatar: 'required|file|image'
import { Request } from '@formidablejs/framework'
export class StorePersonRequest extends Request {
rules() {
return {
avatar: 'required|file|image'
}
}
}
For a list of available validation rules, see the Validation documentation.
Type-safe
When using TypeScript, you may generate types based on your request rules. You may do this for the purpose of type-hinting your request within your forms. This works with Imba (SPA), Vue, React, and Svelte.
This feature is only available when using TypeScript as the default language and nodemon as the default development mode.
Generating Types
To generate types, you may use the types:generate
Craftsman command:
node craftsman types:generate
This command will generate types for all of your request rules. The generated types will be placed in the app/Types/Forms
directory.
Using Generated Types
Once you have generated your types, you may use them in your frontend forms. For example, let's assume we have a StorePersonRequest
class that contains the following rules:
import { Request } from '@formidablejs/framework'
export class StorePersonRequest extends Request {
rules() {
return {
first_name: 'required|string',
last_name: 'required|string',
email: 'required|email',
phone: 'nullable|string',
address: 'nullable|string',
}
}
}
After running the types:generate
command, we will have a StorePersonForm
type generated in the app/Types/Forms
directory:
type StorePersonForm = {
first_name: string
last_name: string
email: string
phone: string | null
address: string | null
}
We may now use this type in our frontend form:
- Imba
- Vue
- React
- Svelte
Create a useStorePersonForm
typescript file that exports a useStorePersonForm
function in the resources/frontend/Pages/People
directory:
import { useForm } from '@formidablejs/view'
export const useStorePersonForm = useForm<StorePersonForm>
And finally, import the useStorePersonForm
function in your Create.imba
file:
import { useStorePersonForm } from './useStorePersonForm'
export tag Create
prop form = useStorePersonForm({
first_name: ''
last_name: ''
email: ''
phone: ''
address: ''
})
...
Create a Create.vue
file in the resources/js/Pages/People
directory:
<script lang="ts" setup>
import { useForm } from '@inertia/vue3'
const form = useForm<StorePersonForm>({
first_name: '',
last_name: '',
email: '',
phone: null,
address: null
})
</script>
...
Create a Create.tsx
file in the resources/js/Pages/People
directory:
import { useForm } from '@inertiajs/react'
export default function Create() {
const { data, setData, post, processing, errors } = useForm<StorePersonForm>({
first_name: '',
last_name: '',
email: '',
phone: null,
address: null
})
...
}
Create a Create.svelte
file in the resources/js/Pages/People
directory:
<script>
import { useForm } from '@inertiajs/svelte'
/** @type {StorePersonForm} form */
let form = useForm({
first_name: '',
last_name: '',
email: '',
phone: null,
address: null
})
</script>
...
Auto-generation
You may also generate types automatically when you run the serve
command with the --dev
flag. You can do this by adding the node craftsman types:generate
command to your package.json
file under development.commands
:
{
"development": {
"mode": "nodemon",
"commands": [
"node craftsman types:generate",
]
}
}
This will generate types for all of your request rules whenever you make changes to your application.