restful - slim php app
Slim: ¿Cómo enviar una respuesta con el encabezado “Content-Type: application/json”? (4)
Tengo esta sencilla API REST, hecha en Slim,
<?php
require ''../vendor/autoload.php'';
function getDB()
{
$dsn = ''sqlite:/home/branchito/personal-projects/slim3-REST/database.sqlite3'';
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$dbh = new PDO($dsn);
foreach ($options as $k => $v)
$dbh->setAttribute($k, $v);
return $dbh;
}
catch (PDOException $e) {
$error = $e->getMessage();
}
}
$app = new /Slim/App();
$app->get(''/'', function($request, $response) {
$response->write(''Bienvenidos a Slim 3 API'');
return $response;
});
$app->get(''/getScore/{id:/d+}'', function($request, $response, $args) {
try {
$db = getDB();
$stmt = $db->prepare("SELECT * FROM students
WHERE student_id = :id
");
$stmt->bindParam('':id'', $args[''id''], PDO::PARAM_INT);
$stmt->execute();
$student = $stmt->fetch(PDO::FETCH_OBJ);
if($student) {
$response->withHeader(''Content-Type'', ''application/json'');
$response->write(json_encode($student));
} else { throw new PDOException(''No records found'');}
} catch (PDOException $e) {
$response->withStatus(404);
$err = ''{"error": {"text": "''.$e->getMessage().''"}}'';
$response->write($err);
}
return $response;
});
$app->run();
sin embargo, no puedo hacer que el navegador me envíe el tipo de contenido de application/json
, ¿siempre envía text/html
? ¿Que estoy haciendo mal?
EDITAR:
Ok, después de dos horas de golpear la cabeza contra la pared, encontré esta respuesta:
https://github.com/slimphp/Slim/issues/1535 (en la parte inferior de una página) que explica lo que sucede, parece que el objeto de response
es inmutable y, como tal, debe devolverse o reasignarse si desea devolverlo después mientras.
Entonces, en lugar de esto:
if($student) {
$response->withHeader(''Content-Type'', ''application/json'');
$response->write(json_encode($student));
return $response;
} else { throw new PDOException(''No records found'');}
Hazlo así:
if($student) {
return $response->withStatus(200)
->withHeader(''Content-Type'', ''application/json'')
->write(json_encode($student));
} else { throw new PDOException(''No records found'');}
Y todo está bien y bien.
Para V3, withJson()
está disponible.
Así que puedes hacer algo como:
return $response->withStatus(200)
->withJson(array($request->getAttribute("route")
->getArgument("someParameter")));
Nota: asegúrate de devolver la $response
porque si la olvidas, la respuesta seguirá apareciendo pero no será application/json
.
Para V3, el método más simple según los documentos Slim es:
$data = array(''name'' => ''Rob'', ''age'' => 40);
return $response->withJson($data, 201);
Esto establece automáticamente el tipo de contenido en application/json;charset=utf-8
y le permite configurar un código de estado HTTP también (por defecto, 200 si se omite)
También puedes usar:
$response = $response->withHeader(''Content-Type'', ''application/json'');
$response->write(json_encode($student));
return $response;
porque withHeader
devuelve nuevo objeto de respuesta. De esa manera tienes más de una escritura y código entre.