finished chapter 8 translation to spanish
This commit is contained in:
123
es/08.3.md
Normal file
123
es/08.3.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# 8.3 REST
|
||||
|
||||
REST es una arquitectura muy popular en internet hoy, porque esta en estándares bien definidos y estrictos y es facil de entender y expandir. Más y más sitios web están basando sus diseños encima de REST. En esta sección, vamos a echarle un vistaso de cerca a la implementación de una arquitectura rEST en Go y (esperando) aprender como usarla para nuestro beneficio.
|
||||
|
||||
## ¿Qué es REST?
|
||||
|
||||
La primera declaración del concepto de REST fue (REpresentational State Transfer) en el año 2000 en la disertación de doctorado de Roy Thomas Fielding, que también es el cofundador del protocolo HTTP. Este especifica las restricciones de arquitectura y los principios, y cualquier cosa implementada en esta arquitectura puede se llamada sistema RESTful.
|
||||
|
||||
Antes que entendamos lo que es REST, necesitamos entender los siguientes conceptos:
|
||||
|
||||
- Recursos
|
||||
|
||||
REST es la Capa de Presentación de la Transferencia de Estado, donde la capa de presentación actualmente es la capa de presentación del recurso.
|
||||
|
||||
Entonces ¿Qué son los recursos? Imagenes, documentos, videos, etc. Todos son ejemplos de recursos que pueden ser localizados por una URI.
|
||||
|
||||
- Representación
|
||||
|
||||
Los recursos son entidades de información específica que pueden ser mostrados de una variedad de maneras en la capa de presentación. Por ejemplo, un documento TXT puede ser representado como un HTML, JSON, XML, etc; una imagen puede representarse como jpg, png, etc.
|
||||
|
||||
Las URIs son utilizadas para indentificar recursos, pero ¿cómo determinamos la manifestación específica? Está referido a los encabezados HTTP Accept y Content-Type; estos dos campos describen la capa de presentación.
|
||||
|
||||
- Estado de transferencia
|
||||
|
||||
Un proceso interactivo es iniciado entre el cliente y el servidor cada vez que visitas una página de un sitio web. Durante este proceso, ciertos datos relacionados con la página actual necesitan ser guardados. Sin embargo, ¡HTTP es un protocolo sin estado! Es obvio que necesitamos guardar este estado del cliente del lado del servidor. Esto prosigue en que si el cliente modifica alguna información y quiere que los cambios persistan, debe exister una manera de informar al servidor sobre el nuevo estado.
|
||||
|
||||
La mayor parte del tiempo, los clientes le informan al servidor los cambios de estado usadno HTTP. Existen cuatro operaciones con las que se hace esto:
|
||||
|
||||
- GET es usado para obteer recursos
|
||||
- POST es usado para crear o actualizar recursos
|
||||
- PUT es usado para actualizar recursos
|
||||
- DELETE elimina recursos
|
||||
|
||||
Para resumir lo anterior:
|
||||
|
||||
- (1) Caca URI representa un recurso.
|
||||
- (2) Existe una capa de presentación para transferir recursos entre clientes y servidores.
|
||||
- (3) Los clientes usan 4 métodos HTTP para implementar la "Capa de Presentación de Transferencia de Estado", permitiéndoles a ellos operar con recursos remotos.
|
||||
|
||||
El principio mas importande de las aplicaciones web que implementan REST es que la interacción entre clientes y servidores es sin estado; cada petición debe encapsular toda la información requerida. Los servidores deberían ser capaces de reiniciarse en cualquier momento sin que los clientes sean notificados. Además, las peticiones pueden ser respondidas por cualquier servidor del mismo servicio, lo cual es ideal para la computación en la nube. Por último, como es sin estado, los clientes pueden cachear la data para mejorar el rendimiento.
|
||||
|
||||
Otro principio importante de un sistema REST es la delaminación, que significa que una capa no tiene una manera de interactuar directamente con componentes de otras capaz. Esto puede limitar la complejidad del sistema y motivar la independencia entre componentes inferiores.
|
||||
|
||||

|
||||
|
||||
Figura 8.5 Arquitectura REST
|
||||
|
||||
Cuando las restricciones RESTful son acatadas juiciosamente, las aplicaciones web pueden escalar para acomodarse a un número masivo de clientes. Usando una arquitectura rEST también podemos reducir las demoras entre clientes y servidores, simplificando la arquitectura y mejorando la visibilidad de los susbistemas.
|
||||
|
||||

|
||||
|
||||
Figure 8.6 Expansibilidad de REST
|
||||
|
||||
## Implementación RESTful
|
||||
|
||||
Go no tiene soporte durecto para REST, pero desde que las aplicaciones RESTful están basadas en HTTP, podemos usar el paquete `net/http` para implementarla nosotros mismos. Por supuesto, primero necesitamos hacer algunas modificaciones antes de implementar completamente REST.
|
||||
|
||||
REST usa diferentes métodos para manejar recursos, dependiendo de la interacción que es requerida por ese recurso. Muchas aplicaciones existentes dicen ser RESTful pero no implementan REST. Voy a categorizar estas aplicaciones en varios niveles dependiendo de que métdos HTTP implementan.
|
||||
|
||||

|
||||
|
||||
Figura 8.7 Niveles de REST
|
||||
|
||||
La figura de arriba nos muestra tres niveles actualmente implementados en REST. puedes escoger no seguir todas las reglas y restricciones de REST cuando estás desarrollando tus aplicaciones propias, porque a veces no encajan en todas las situaciones. Las aplicaciones RESTful usan todos los métodos HTTP incluyendo `DELETE` y `PUT`, pero en muchos casos, los clientes solo envían peticiones `GET` y `POST`.
|
||||
|
||||
- El estándar de HTML permite a los clientes enviar `GET` y `POST` a través de enlaces y formularios. No es posible enviar peticiones `PUT` o `DELETE` sin soporte de AJAX.
|
||||
- Algunos firewalls interceptan peticiones `PUT` y `DELETE` y los clientes tienen `POST` para implementarlos. Los servicios completamente RESTful usan los métodos originales HTTP y los reestablecen.
|
||||
|
||||
Podemos simular las peticiones `PUT` y `DELETE` agregando un campo oculto llamado `_method` en nuestras peticiones `POST`, sin embargo estas peticiones tienen que ser convertidas en el servidor antes de que puedan ser procesadas. En mis aplicaciones personales, uso este flujo de trabajo para implmentar iterfaces REST. Las interfaces RESTful son fáciles de implementar en Go, como se puede ver en el siguiente ejemplo:
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/drone/routes"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func getuser(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
uid := params.Get(":uid")
|
||||
fmt.Fprintf(w, "you are get user %s", uid)
|
||||
}
|
||||
|
||||
func modifyuser(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
uid := params.Get(":uid")
|
||||
fmt.Fprintf(w, "you are modify user %s", uid)
|
||||
}
|
||||
|
||||
func deleteuser(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
uid := params.Get(":uid")
|
||||
fmt.Fprintf(w, "you are delete user %s", uid)
|
||||
}
|
||||
|
||||
func adduser(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
uid := params.Get(":uid")
|
||||
fmt.Fprint(w, "you are add user %s", uid)
|
||||
}
|
||||
|
||||
func main() {
|
||||
mux := routes.New()
|
||||
mux.Get("/user/:uid", getuser)
|
||||
mux.Post("/user/:uid", modifyuser)
|
||||
mux.Del("/user/:uid", deleteuser)
|
||||
mux.Put("/user/", adduser)
|
||||
http.Handle("/", mux)
|
||||
http.ListenAndServe(":8088", nil)
|
||||
}
|
||||
```
|
||||
Este ejemplo muestra como puedes escribir aplicaciones REST muy básicas. Nuestros recursos son usuarios y usamos diferentes funciones para diferentes métods. Aquí, importamos un paquete de terceros llamado `github.com/drone/routes`. Ya hemos cubierto como implementar un manejador de rutas personalizado en capítulos anteriores. El paquete `drone/routes` implementa un mapeo de rutas muy conveniente de seguir y muy fácil para implementar arquitecturas REST. Como puedes ver, REST requiere que implementes diferente lógica para cada método HTTP de el mismo recurso.
|
||||
|
||||
## Resumen
|
||||
|
||||
REST es un estilo de arquitectura web, construido en las experiencias pasadas con WWW: sin estado, centrado en los recursos, uso completo de protocolos HTTP y URI y la provisión de interfaces unificadas. Estas consideraciones de diseño superior le han permitido a REST convertirse en estándar mas popular para servicios web. En cierta manera, al enfatizar la carga en las URIs y el uso de estándares tempranos de Internet como HTTP, REST a pavimentado el camino para aplicaciones grandes y escalables. Actualmente el soporte que Go da para REST es muy básico, sin embargo, al implementar rutas personalizads y diferentes manejadores de petición para cada tipo de petición HTTP, podemos alcanzar una arquitectura RESTful en nuestras aplicaciones web de Go.
|
||||
|
||||
## Enlaces
|
||||
|
||||
- [Índice](preface.md)
|
||||
- Sección Previa: [WebSocket](08.2.md)
|
||||
- Siguiente sección: [RPC](08.4.md)
|
||||
400
es/08.4.md
Normal file
400
es/08.4.md
Normal file
@@ -0,0 +1,400 @@
|
||||
# 8.4 RPC
|
||||
|
||||
En secciones anteriores hablamos sobre como escribir aplicaciones de red basadas en Sockets y HTTP. Aprendimos que ambos usan un modelo de "intercambio de información", en donde los clientes envían peticiones y los servidores las responden. Este tipo de intercambio está basado en un formato específico que ambos lados conocen y saben como comunicarse con el. Sin embargo, existen muchas aplicaciones independientes que no usan este modelo, pero en vez de eso llaman servicios como si llamaran funciones normales.
|
||||
|
||||
RPC fue creado para ser el modo de llamado de funciones para sistemas de red. Los clientes ejecutan RPC como si fueran funciones nativas. excepto que empaquetan la función y los parámetros y los envían a través de la red a un servidor. El servidor puede desempaquetar los parámetros y procesar la petición, ejecutando los resultados de vuelta hacia el cliente.
|
||||
|
||||
En ciencias de la computación, un llamado de procedimiento remoto (Remote Call Procedure RPC) es un tipo de comunicación inter proceso que permite a un programa de computador ejecutar una subrutina o precedimiento en otro espacio de direcciones (usualmente otro computador en un red compartida) sin que el programador específicamente codifique los detalles para esta interacción remota. Esto es, el programador escribe el mismo código ya sea que la subrutina se ejecute local o remotamente. Cuando el software en cuestión usa principios orientados a objetos, el RPC es llamado invocación remota o invocación remota de métodos.
|
||||
|
||||
## Principio de trabajo de RPC
|
||||
|
||||

|
||||
|
||||
Figura 8.8 Principio de trabajo de RPC
|
||||
|
||||
Normalmente, un llamado RPC de un cliente a un servidor tiene diez pasos:
|
||||
|
||||
- 1. Llamar al manejador del cliente que ejecute la transmisieon de los argumentos.
|
||||
- 2. Llamar al kernel del sistema para enviar mensajes de red.
|
||||
- 3. Enviar mensajes a los hosts remotos.
|
||||
- 4. El servidor recibe y maneja los argumentos.
|
||||
- 5. Se ejecuta el proceso remoto.
|
||||
- 6. Se retorna el resultado de la ejecución al manejador.
|
||||
- 7. El servidor maneja la llamada a un kernel remoto.
|
||||
- 8. El mensaje es enviado al kernel local.
|
||||
- 9. El cliente maneja el mensaje del kernel.
|
||||
- 10. El cliente obtiene los resultados del manejador correspondiente.
|
||||
|
||||
## RPC en Go
|
||||
|
||||
Go tiene soporte oficial para RPC en su librería estándar en tres niveles, que son TCP, HTTP y JSON. Nota que Go RPC no es como otro sistema tradicional RPC. Requiere que uses aplicaciones Go en cliente y servidor porque codifica el contenido usando Gob.
|
||||
|
||||
Funciones que Go RPC deben seguir las siguientes reglara para tener acceso remoto, de otra manera, las llamadas serán ignoradas.
|
||||
|
||||
- Las funciones deben ser exportadas (Primera letra en mayúscula)
|
||||
- Las funciones deben tener dos argumentos con tipos exportados.
|
||||
- El primer argumento es para recibir del cliente y el segundo debe ser un puntero y debe ser para responderle al cliente.
|
||||
- Las funciones deben tener valor de reporte o un tipo de error.
|
||||
|
||||
Por ejemplo:
|
||||
```
|
||||
func (t *T) MethodName(argType T1, replyType *T2) error
|
||||
```
|
||||
Donde T, T1 y T2 deben estar codificados en el paquete `package/gob`.
|
||||
|
||||
Cualquier tipo de RPC tiene que pasar por la red para transferir datos. Go RPC puede usar HTTP o TCO. Los beneficios de usar HTTP es que puedes reusar algunas funciones del paquete `net/http`.
|
||||
|
||||
### HTTP RPC
|
||||
|
||||
Lado del servidor HTTP:
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/rpc"
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
type Quotient struct {
|
||||
Quo, Rem int
|
||||
}
|
||||
|
||||
type Arith int
|
||||
|
||||
func (t *Arith) Multiply(args *Args, reply *int) error {
|
||||
*reply = args.A * args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Arith) Divide(args *Args, quo *Quotient) error {
|
||||
if args.B == 0 {
|
||||
return errors.New("divide by zero")
|
||||
}
|
||||
quo.Quo = args.A / args.B
|
||||
quo.Rem = args.A % args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
arith := new(Arith)
|
||||
rpc.Register(arith)
|
||||
rpc.HandleHTTP()
|
||||
|
||||
err := http.ListenAndServe(":1234", nil)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
}
|
||||
```
|
||||
Registramos un servicio RPC de Arith, luego registramos este servicio a través de `rpc.HandleHTTP`. Después de eso, somos capaces de transferir datos a través de HTTP.
|
||||
|
||||
Código del lado del cliente:
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/rpc"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
type Quotient struct {
|
||||
Quo, Rem int
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Println("Usage: ", os.Args[0], "server")
|
||||
os.Exit(1)
|
||||
}
|
||||
serverAddress := os.Args[1]
|
||||
|
||||
client, err := rpc.DialHTTP("tcp", serverAddress+":1234")
|
||||
if err != nil {
|
||||
log.Fatal("dialing:", err)
|
||||
}
|
||||
// Sincronizamos la llamada
|
||||
args := Args{17, 8}
|
||||
var reply int
|
||||
err = client.Call("Arith.Multiply", args, &reply)
|
||||
if err != nil {
|
||||
log.Fatal("arith error:", err)
|
||||
}
|
||||
fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
|
||||
|
||||
var quot Quotient
|
||||
err = client.Call("Arith.Divide", args, ")
|
||||
if err != nil {
|
||||
log.Fatal("arith error:", err)
|
||||
}
|
||||
fmt.Printf("Arith: %d/%d=%d remainder %d\n", args.A, args.B, quot.Quo, quot.Rem)
|
||||
|
||||
}
|
||||
```
|
||||
Compilamos el cliente y el servidor separadamente y luego iniciamos el servidor y el cliente. Entonces puedes tener algo similar después que ingreses algunos datos.
|
||||
```
|
||||
$ ./http_c localhost
|
||||
Arith: 17*8=136
|
||||
Arith: 17/8=2 remainder 1
|
||||
```
|
||||
Como puedes ver, definimos una estructura para el tipo de retorno. La usamos como argumento de función en el lado del servidor, y como el tipo del segundo y tercer argumento del cliente `client.Call`. Esta llamada es muy importante. Tiene tres argumentos, donde el primero es el nombre de la función que va a ser llamado, el segundo es el argumento que quieres pasar y el último es el valor de retorno (de tipo puntero). Hasta aquí podemos ver que es fácil implementar RPC en Go.
|
||||
|
||||
### TCP RPC
|
||||
|
||||
Vamos a probar el RPC que está basado en TCP, aquí esta el código del servidor:
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/rpc"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
type Quotient struct {
|
||||
Quo, Rem int
|
||||
}
|
||||
|
||||
type Arith int
|
||||
|
||||
func (t *Arith) Multiply(args *Args, reply *int) error {
|
||||
*reply = args.A * args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Arith) Divide(args *Args, quo *Quotient) error {
|
||||
if args.B == 0 {
|
||||
return errors.New("divide by zero")
|
||||
}
|
||||
quo.Quo = args.A / args.B
|
||||
quo.Rem = args.A % args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
arith := new(Arith)
|
||||
rpc.Register(arith)
|
||||
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", ":1234")
|
||||
checkError(err)
|
||||
|
||||
listener, err := net.ListenTCP("tcp", tcpAddr)
|
||||
checkError(err)
|
||||
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
rpc.ServeConn(conn)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func checkError(err error) {
|
||||
if err != nil {
|
||||
fmt.Println("Fatal error ", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
```
|
||||
La diferencia entre HTTP RPC y TCP RPC es que tenemos que controlar las conexiones por nuestra propia cuenta si usamos TCP RPC, entonces pasamos las conexiones para el procesamiento RPC.
|
||||
|
||||
Como puedes adivinar, este puede ser un patrón que se bloquea. Eres libre de usar rutinas para esta aplicación en un experimento mas avanzado.
|
||||
|
||||
Código del lado del cliente:
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/rpc"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
type Quotient struct {
|
||||
Quo, Rem int
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Println("Usage: ", os.Args[0], "server:port")
|
||||
os.Exit(1)
|
||||
}
|
||||
service := os.Args[1]
|
||||
|
||||
client, err := rpc.Dial("tcp", service)
|
||||
if err != nil {
|
||||
log.Fatal("dialing:", err)
|
||||
}
|
||||
// Sincronizamos las llamadas
|
||||
args := Args{17, 8}
|
||||
var reply int
|
||||
err = client.Call("Arith.Multiply", args, &reply)
|
||||
if err != nil {
|
||||
log.Fatal("arith error:", err)
|
||||
}
|
||||
fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
|
||||
|
||||
var quot Quotient
|
||||
err = client.Call("Arith.Divide", args, ")
|
||||
if err != nil {
|
||||
log.Fatal("arith error:", err)
|
||||
}
|
||||
fmt.Printf("Arith: %d/%d=%d remainder %d\n", args.A, args.B, quot.Quo, quot.Rem)
|
||||
|
||||
}
|
||||
```
|
||||
La única diferencia en el lado del cliente es que los clientes HTTP usan DialHTTP donde los clientes TCP usan Dial(TCP).
|
||||
|
||||
### JSON RPC
|
||||
|
||||
JSON RPC codifica la información en JSON en vez de Gob. Veamos un ejemplo de Go usando JSON RPC en el servidor.
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
type Quotient struct {
|
||||
Quo, Rem int
|
||||
}
|
||||
|
||||
type Arith int
|
||||
|
||||
func (t *Arith) Multiply(args *Args, reply *int) error {
|
||||
*reply = args.A * args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Arith) Divide(args *Args, quo *Quotient) error {
|
||||
if args.B == 0 {
|
||||
return errors.New("divide by zero")
|
||||
}
|
||||
quo.Quo = args.A / args.B
|
||||
quo.Rem = args.A % args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
arith := new(Arith)
|
||||
rpc.Register(arith)
|
||||
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", ":1234")
|
||||
checkError(err)
|
||||
|
||||
listener, err := net.ListenTCP("tcp", tcpAddr)
|
||||
checkError(err)
|
||||
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
jsonrpc.ServeConn(conn)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func checkError(err error) {
|
||||
if err != nil {
|
||||
fmt.Println("Fatal error ", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
```
|
||||
JSON RPC está basado en TCP y no soporta HTTP todavía.
|
||||
|
||||
El código del cliente:
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/rpc/jsonrpc"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
type Quotient struct {
|
||||
Quo, Rem int
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Println("Usage: ", os.Args[0], "server:port")
|
||||
log.Fatal(1)
|
||||
}
|
||||
service := os.Args[1]
|
||||
|
||||
client, err := jsonrpc.Dial("tcp", service)
|
||||
if err != nil {
|
||||
log.Fatal("dialing:", err)
|
||||
}
|
||||
// Sincronizamos llamadas
|
||||
args := Args{17, 8}
|
||||
var reply int
|
||||
err = client.Call("Arith.Multiply", args, &reply)
|
||||
if err != nil {
|
||||
log.Fatal("arith error:", err)
|
||||
}
|
||||
fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
|
||||
|
||||
var quot Quotient
|
||||
err = client.Call("Arith.Divide", args, ")
|
||||
if err != nil {
|
||||
log.Fatal("arith error:", err)
|
||||
}
|
||||
fmt.Printf("Arith: %d/%d=%d remainder %d\n", args.A, args.B, quot.Quo, quot.Rem)
|
||||
|
||||
}
|
||||
```
|
||||
## Resumen
|
||||
|
||||
Go tiene buen soporte para implementaciones de RPC sobre HTTP, TCP y JSON, que nos permite fácilmente desarrollar aplicaciones we distrubidas: sinembargo, es lamentable que Go no tenga soporte para SOAP RPC incluido, sin embargo algunas paquetes de terceros de código abierto ofrecen esto.
|
||||
|
||||
## Enlaces
|
||||
|
||||
- [Índice](preface.md)
|
||||
- Sección Previa: [REST](08.3.md)
|
||||
- Siguiente Sección: [Summary](08.5.md)
|
||||
11
es/08.5.md
Normal file
11
es/08.5.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# 8.5 Resumen
|
||||
|
||||
En este capítulo, he introducido muchos conceptos conocidos de modelos de desarrollo de aplicaciones web. En la seccieon 8.1 describimos el funcionamiento básico de programación por sockets. Por la revolución acelerada de las tecnologías de red e infraestructura, y dado que los Sockets son una piedra angular de estos cambios, debes especializarte en estos conceptos en orden de ser un desarrollador web competente. En la sección 8.2 hablamos los WebSockets de HTML5 que soporta comunicación en ambas vías entre el cliente y el servidor elimitando la necesidad del polling con AJAX. En la sección 8.3 implementamos una aplicación usando la arquitectura REST, que particularmente es muy apropiada para el desarrollo de APIs sobre la red; gracias al rápido crecimiento de las aplicaciones móviles, creo que las APIs RESTful pueden ser una tendencia que siga. En la sección 8.4, hablamos sobre RPC en Go.
|
||||
|
||||
Go provee un excelente soporte para estos cuatro tipos de métodos de desarrollo. Nota que el paquete `net` y sus subpaquetes es el lugar donde Go coloca las herramientas de red. Si quieres un conocimiento mas profundo de los detalles de implementación, deberías leer el código fuente de esos paquetes.
|
||||
|
||||
## Enlaces
|
||||
|
||||
- [Índice](preface.md)
|
||||
- Sección previa: [RPC](08.4.md)
|
||||
- Siguiente Capítulo: [Seguridad y Encripción](09.0.md)
|
||||
Reference in New Issue
Block a user