Servidores simulados dinámicos y con estado

APIGit

2022-10-15

APIGit admite servidores simulados dinámicos, con estado y programables para simular cualquiera de las lógicas comerciales complejas con facilidad. Los mensajes de solicitud HTTP se manejan definiendo rutas usando mock.define() y proporcionando un patrón de URL, un verbo HTTP y una función de devolución de llamada. Por ejemplo:

mock.define('/users', 'GET', function(req, res) {
    ...
  })

o, para un método POST:

mock.define('/users', 'POST', function(req, res) {
    ...
  })

Se admiten métodos HTTP estándar como 'DELETE', 'PUT' y 'OPTIONS'. La función de devolución de llamada que proporciona siempre se pasa dos objetos como parámetros, los objetos de solicitud y respuesta. El objeto Solicitud contiene todos los datos relacionados con la solicitud entrante, como encabezados, carga útil del cuerpo y parámetros. Usamos el objeto Response para generar respuestas a la solicitud.

Ampliemos el ejemplo anterior y comencemos a crear un servicio CRUD básico para los usuarios. Primero, definamos una ruta para devolver un conjunto de usuarios:

mock.define('/users', 'GET', function(req, res) {
    var users = [ 
      { username: "dave", email: "dave@gmail.com" },
      { username: "john", email: "john@gmail.com" }
    ]
  
    return res.json(users)
  })

La llamada res.json enviará una respuesta JSON a la aplicación que llama. Recuerde llamar a una función de respuesta en el objeto res, sin ella, su servicio expirará y no devolverá un resultado exitoso. Exploraremos las otras funciones de respuesta disponibles más adelante.

Agreguemos soporte para filtrado basado en la edad del usuario usando parámetros de consulta. req.query es un objeto que contiene la cadena de consulta analizada, cuyo valor predeterminado es {}. Si enviamos una solicitud de 'GET /users?age=30', podemos acceder al valor de edad con req.query.age:

mock.define('/users', 'GET', function(req, res) {
    var users = [
      { username: "dave", email: "dave@gmail.com", age: 32 },
      { username: "john", email: "john@gmail.com", age: 30 }
    ]
  
    if (req.query.age) {
      // convert req.query.age from String to a Number before filtering
      return res.json(_.filter(users, { 'age': Number(req.query.age) }))
    }
  
    return res.json(users)
  })

Usamos la función LoDash _.filter para extraer una matriz de usuarios que coinciden con la edad proporcionada. Si ningún usuario cumple los criterios de edad, se devuelve una matriz vacía. La biblioteca completa de LoDash está disponible para usar, proporciona funciones útiles para manipular matrices y objetos.

Para crear nuestra ruta para recuperar un solo usuario, usamos parámetros de ruta como parte de la ruta URL del servicio. Los parámetros de ruta se especifican usando la sintaxis {route_param_name}, por lo que en nuestro ejemplo, la ruta URL para recuperar un usuario por su nombre de usuario será/users/{username}. El req.params es un objeto que contiene propiedades asignadas a los parámetros de ruta nombrados y nuestro nombre de usuario estará disponible como req.params.username.

mock.define('/users/{username}', 'GET', function(req, res) {
    var users = [
      { username: "dave", email: "dave@gmail.com", age: 32 },
      { username: "john", email: "john@gmail.com", age: 30 }
    ]
  
    // respond with the user or an empty object if user doesnt exist
    return res.json(_.find(users, { 'username': req.params.username }) || {})
  })

Agreguemos una ruta para crear usuarios. Verificaremos que se haya enviado un nombre de usuario con la solicitud y responderemos con un error 400 si falta. Se puede acceder a los datos que se envían como una carga útil del cuerpo en las solicitudes POST en el objeto req.body.

mock.define('/users', 'POST', function(req, res) {
    // validate username is present
    if (req.body.username === undefined) {
      return res.json(400, { error: { message: "Missing username" } })
    }
  
    return res.json({ status: "ok" })
  })

De forma predeterminada, todas las respuestas devuelven un 200. Si se proporciona un número como único parámetro para res.json, se le asigna una cadena de cuerpo de respuesta. Por ejemplo, 400 responderá con "Solicitud incorrecta". Hemos especificado un mensaje de error personalizado en el ejemplo anterior.

Ese es un comienzo sólido, puede hacer mucho con los servicios que devuelven respuestas enlatadas simples, pero solo lo llevan hasta cierto punto. Pasemos a agregar un comportamiento realista a nuestros servicios mediante la persistencia de datos y la generación dinámica de respuestas.