Saltar al contenido

Angular: serializar/deserializar en objetos JSON HttpRequest y HttpResponse

Si encuentras algún problema con tu código o trabajo, recuerda probar siempre en un entorno de testing antes añadir el código al trabajo final.

Solución:

Aunque recomendaría un Service Worker para el almacenamiento en caché, la forma más fácil que conozco es clonar la solicitud/respuesta y luego obtener su información:

function serializeRequest(req: HttpRequest): string 
    const request = req.clone(); // Make a clone, useful for doing destructive things
    return JSON.stringify(
        headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer
            request.headers.keys.map( // Get all of the headers
                (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
            )
        ),
        method: request.method, // The Request Method, e.g. GET, POST, DELETE
        url: request.url, // The URL
        params: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer
            request.headers.keys.map( // Get all of the headers
                (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
            )
        ), // The request parameters
        withCredentials: request.withCredentials, // Whether credentials are being sent
        respnseType: request.responseType, // The response type
        body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone
    )

De manera similar, también podemos serializar la respuesta (suponiendo que T es compatible con JSON, una suposición justa en una solicitud HTTP):

function serializeResponse(res: HttpResponse): string 
    const response = res.clone();
    return JSON.stringify(
        headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer
            response.headers.keys.map( // Get all of the headers
                (key: string) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers
            )
        ),
        status: response.status,
        statusText: response.statusText,
        url: response.url,
        body: response // Serialize the body, all well and good since we are working on a clone
    )

Y luego, dado que guardamos toda la información requerida, la deserialización es un paseo por el parque:

function deserializeRequest(req: string): HttpRequest 
    const request = JSON.parse(req);
    const headers = new HttpHeaders(request.headers);
    const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs
    for(let parameter in request.params)
        request.params[parameter].forEach((paramValue: string) => params.append(parameter, paramValue));
    
    return new HttpRequest(request.method, request.url, request.body, 
        headers,
        params,
        respnseType: request.respnseType,
        withCredentials: request.withCredentials
    );


function deserializeResponse(res: string): HttpResponse 
    const response = JSON.parse(res);
    const headers = new HttpHeaders(response.headers);
    return new HttpRequest(
        headers,
        body: response.body,
        status: response.status,
        statusText: response.statusText,
        url: response.url,
    );

Playground de todo (aunque, lamentablemente, los tipos angulares no se cargan correctamente)

Tenga en cuenta que no he probado esto en ningún entorno, por lo que se proporciona TAL CUAL, y no estoy seguro de cómo expect manejaría dos HttpHeaders/HttpParamsespecialmente porque es posible que no tengan exactamente el mismo orden.

Acuérdate de que tienes la capacidad de agregar una reseña si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *