Skip to main content

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 of FormRequest.

Accessing The Request

Formidable loads requests to route actions as first parameters by default:

app/Http/Controllers/TaskController.ts
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:

app/Http/Controllers/TaskController.ts
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:

const host: string = request.getHost()

Retrieving The Request Origin

The getOrigin method returns the request's origin:

const origin: string = request.getOrigin()

You may also use the getFullOrigin method to retrieve the full origin including the protocol:

const fullOrigin: string = request.getFullOrigin()

Retrieving The Request Origin protocol

The getOriginProtocol method returns the request's protocol:

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:

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:

if (request.isUrl('tasks/store')) {
// do somthing
}

You may also use pathIs. You may use the * character as a wildcard when utilizing this method:

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:

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:

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:

const slug: string|null = request.param('slug')

To retrieve all route parameters, you may use the params method:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

const file = request.file('avatar').first()

Retrieving All Files

The all method may be used to retrieve all of the files in the collection:

const files = request.file('avatar').all()

You may also use the get method to retrieve all of the files in the collection:

const files = request.file('avatar').get()

Retrieving First File

The first method may be used to retrieve the first file in the collection:

const file = request.file('avatar').first()

Retrieving Last File

The last method may be used to retrieve the last file in the collection:

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:

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:

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:

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:

request.file('avatar').each(file => {
// do something
})

Counting Files

You may use the count method to count the number of files in the collection:

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:

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:

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:

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:

PropertyDescription
nameThe name of the file.
filenameThe name of the file.
encodingThe encoding of the file.
mimeThe MIME type of the file.
mimetypeThe MIME type of the file.
typeThe MIME type of the file.
pathThe path to the file.
extensionThe extension of the file.
extThe extension of the file.
sizeThe size of the file in MB.

For example, to retrieve the extension of an uploaded file, you may use the extension getter:

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:

app/Http/Requests/StorePersonRequest.ts
import { Request } from '@formidablejs/framework'

export class StorePersonRequest extends Request {
rules() {
return {
avatar: 'required|file|image'
}
}
}
info

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.

info

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:

app/Http/Requests/StorePersonRequest.ts
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:

app/Types/Forms/StorePersonForm.ts
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:

Create a Create.vue file in the resources/js/Pages/People directory:

resources/js/Pages/People/Create.vue
<script lang="ts" setup>
import { useForm } from '@inertia/vue3'

const form = useForm<StorePersonForm>({
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:

package.json
{
"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.