---
name: "Web::MREST::Resource"
section: "3pm"
platform: "linux"
package: "libweb-mrest-perl"
version: "0.290-1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Web::MREST::Resource"
---

# Web::MREST::Resource(3pm)

HTTP request/response cycle

## NAME

App::MREST::Resource - HTTP request/response cycle

## SYNOPSIS

In `"YourApp/Resource.pm"`:

```
    use parent 'Web::MREST::Resource';
```

In PSGI file:

```
    use Web::Machine;
    Web::Machine->new(
        resource => 'App::YourApp::Resource',
    )->to_app;
```

It is important to understand that the Web::Machine object created is actually blessed into `"YourApp::Resource"`. The line of inheritance is:

```
    YourApp::Resource
        -> Web::MREST::Resource
            -> Web::Machine::Resource
                -> Plack::Component
```

## DESCRIPTION

Your application should not call any of the routines in this module directly. They are called by Web::Machine during the course of request processing. What your application can do is provide its own versions of selected routines.

## METHODS

### Context methods

Methods for manipulating the context, a hash where we accumulate information about the request.

*context*

Constructor/accessor

*push\_onto\_context*

Takes a hashref and "pushes" it onto `"$self->{'context'}"` for use later on in the course of processing the request.

### Status declaration methods

Although Web::Machine takes care of setting the HTTP response status code, but when we have to override Web::Machine's value we have this "MREST declared status" mechanism, which places a `"declared_status"` property in the context. During finalization, the HTTP status code placed in this property overrides the one Web::Machine came up with.

*mrest\_declare\_status*

This method takes either a ready-made App::CELL::Status object or, alternatively, a PARAMHASH. In the former case, an HTTP status code can be "forced" on the response by including a `"http_code"` property in the object. In the latter case, the following keys are recognized (and all of them are optional):

- level

  App::CELL::Status level, can be any of the strings accepted by that module. Defaults to 'ERR'.

- code

  The HTTP status code to be applied to the response. Include this only if you  need to override the code set by Web::Machine.

- explanation

  Text explaining the status - use this to comply with RFC2616. Defaults to '\<NONE\>'.

- permanent

  Boolean value for error statuses, specifies whether or not the error is permanent - use this to comply with RFC2616. Defaults to true.

*mrest\_declared\_status\_code*

Accessor method, gets just the HTTP status code (might be undef); and allows setting the HTTP status code, as well, by providing an argument.

*mrest\_declared\_status\_explanation*

Accessor method, gets just the explanation (might be undef). Does not allow changing the explanation - for this, nullify the  declared status and declare a new one.

### status\_declared

Boolean method - checks context for presence of 'declared\_status' property. If  it is present, the value of that property is returned, just as if we had done `"$self->context->{'declared_status'}"`. Otherwise, undef (false) is returned.

### declared\_status

Synonym for `"status_declared"`

### nullify\_declared\_status

This method nullifies any declared status that might be pending.

### FSM Part One

The following methods override methods defined by Web::Machine::Resource. They correspond to what the Web::MREST calls "Part One" of the FSM. To muffle debug-level log messages from this part of the FSM, set `$muffle`{1} = 1 (above).

*service\_available (B13)*

This is the first method called on every incoming request.

*mrest\_service\_available*

Hook. If you overlay this and intend to return false, you should call  `"$self->mrest_declare_status"` !!

*known\_methods (B12)*

Returns the value of `"MREST_SUPPORTED_HTTP_METHODS"` site parameter

*uri\_too\_long (B11)*

Is the URI too long?

*allowed\_methods (B10)*

Determines which HTTP methods we recognize for this resource. We return these methods in an array. If the requested method is not included in the array, Web::Machine will return the appropriate HTTP error code.

RFC2616 on 405: "The response MUST include an Allow header containing a list of valid methods for the requested resource." -\> this is handled by Web::Machine, but be aware that if the methods arrayref returned by allowed\_methods does not include the current request method, allow\_methods gets called again.

*malformed\_request (B9)*

A true return value from this method aborts the FSM and triggers a "400 Bad Request" response status.

*mrest\_malformed\_request*

Hook

*is\_authorized (B8)*

Authentication method - should be implemented in the application.

*forbidden (B7)*

Authorization method - should be implemented in the application.

*valid\_content\_headers (B6)*

Receives a Hash::MultiValue object containing all the `"Content-*"` headers in the request. Checks these against \<\< `$site`-\>MREST\_VALID\_CONTENT\_HEADERS \>\>, returns false if the check fails, true if it passes.

*known\_content\_type (B5)*

The assumption for `"PUT"` and `"POST"` requests is that they might have an accompanying request entity, the type of which should be declared via a `"Content-Type"` header. If the content type is not recognized by the application, return false from this method to trigger a "415 Unsupported Media Type" response.

The basic content-types (major portions only) accepted by the application should be listed in `"$site->MREST_SUPPORTED_CONTENT_TYPES"`. Override this method if that's not good by you.

*valid\_entity\_length (B4)*

Called by Web::Machine with one argument: the length of the request  body. Return true or false.

*charsets\_provided*

This method causes Web::Machine to encode the response body (if any) in UTF-8.

### FSM Part Two (Content Negotiation)

See Web::MREST::Entity.

### FSM Part Three (Resource Existence)

### resource\_exists (G7)

The initial check for resource existence is the URI-to-resource mapping,  which has already taken place in `"allowed_methods"`. Having made it to here, we know that was successful.

So, what we do here is call the handler function, which is expected to  return an App::CELL::Status object. How this status is interpreted is left up to the application: we pass the status object to the `"mrest_resource_exists"` method, which should return either true or false.

For GET and POST, failure means 404 by default, but can be overrided  by calling `"mrest_declare_status"` from within `"mrest_resource_exists"`.

For PUT, success means this is an update operation and failure means insert.

For DELETE, failure means "202 Accepted" - i.e. a request to delete a resource that doesn't exist is accepted, but nothing actually happens.

### allow\_missing\_post

If the application wishes to allow POST to a non-existent resource, this method will need to be overrided.

### post\_is\_create

### mrest\_post\_is\_create

Looks for a 'post\_is\_create' property in the context and returns 1 or 0, as appropriate.

### create\_path

### mrest\_create\_path

This should always return \_something\_ (never undef)

### create\_path\_after\_handler

This is set to true so we can set `"$self->context->{'create_path'}"` in the handler.

### process\_post

This is where we construct responses to POST requests that do not create a new resource. Since we expect our resource handlers to "do the needful", all we need to do is call the resource handler for pass two.

The return value should be a Web::Machine/HTTP status code like, e.g., \\200 - this ensures that Web::Machine does not attempt to  encode the response body, as in our case this would introduce a double- encoding bug.

### delete\_resource

This method is called on DELETE requests and is supposed to tell Web::Machine whether or not the DELETE operation was enacted. In our case, we call the resource handler (pass two).

### finish\_request

This overrides the Web::Machine method of the same name, and is called just before the final response is constructed and sent. We use it for adding certain headers in every response.
