Bonjour, c'est Yamauchi! Une grosse canette a eu lieu dans notre succursale de Fukuoka le 14 novembre 2020. C'est un nom qui semble être quelque chose comme passer la nuit, mais même si je le fais depuis au moins un mois depuis environ un an et demi, je n'ai encore qu'une excursion d'une journée. .. .. Eh bien, mettons-le de côté, et je vais vous présenter l'outil que j'ai créé cette fois! Au fait, je suis un super débutant dans le langage Go, et c'est la première fois que je crée quelque chose comme un outil, donc je pense qu'il y a divers problèmes avec le code.
Pour cet outil, j'ai créé l'API et le côté qui la touche séparément. Ceci est le référentiel. API:https://github.com/y-keisuke/pokemon Côté frappant: https://github.com/y-keisuke/pokemon_command Veuillez le regarder avec le sentiment que vous allez l'examiner w
Je voulais vraiment les rassembler dans un référentiel, mais je ne savais pas si c'était possible, alors j'ai divisé les référentiels, donc seules les commandes que j'ai utilisées plus tard ont des commandes attachées aux référentiels. Cela n'a pas d'importance.
C'est pourquoi c'est une introduction approximative, donc le mouvement est comme ça ↓ (Désolé pour le mouvement lent, j'ai frappé un total de 4 fois)
C'est assez dur, mais ça ressemble à ça.
Tout d'abord, côté API, j'ai emprunté json au dépôt ici ↓. https://github.com/fanzeyi/pokemon.json/blob/master/pokedex.json
db.go Je voulais vraiment préparer une base de données, mais c'était gênant, j'ai donc utilisé json tel quel ← C'est «db.go».
package db
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
type PokemonCollection struct {
Pokemons []PokemonData
}
type PokemonData struct {
Id int `json:"id"`
Name PokemonName `json:"name"`
Type []string `json:"type"`
Base PokemonBase `json:"base"`
}
type PokemonName struct {
English string `json:"english"`
Japanese string `json:"japanese"`
Chinese string `json:"chinese"`
French string `json:"french"`
}
type PokemonBase struct {
HP int `json:"hp"`
Attack int `json:"attack"`
Defense int `json:"defense"`
SpAttack int `json:"spattack"`
SpDefense int `json:"spdefense"`
Speed int `json:"speed"`
}
func GetPokemonCollection() PokemonCollection {
raw, err := ioutil.ReadFile("./pokedex.json")
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
var pokemonCollection PokemonCollection
json.Unmarshal(raw, &pokemonCollection)
return pokemonCollection
}
Certaines des structures définies ci-dessus sont exactement les mêmes que celles de json.
La structure a légèrement changé par rapport au json emprunté.
Le GetPokemonCollection ()
défini ici place les données json dans la structure.
En particulier
json.Unmarshal(raw, &pokemonCollection)
Cette partie est emballée dans la structure. Cette structure est utilisée comme DB.
main.go
Vient ensuite «main.go».
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
pokemon2 "pokemon/pokemon"
)
func pokemonToJson(w http.ResponseWriter, r *http.Request) {
name := r.FormValue("name")
pokemon, err := pokemon2.GetPokemonBy(name)
//Je ne savais pas comment renvoyer json des informations d'erreur ici
if err != nil {
log.Writer()
http.Error(w, fmt.Sprintf("{\"err\":\"%s\"}", err), 200)
return
}
pokemonJson, _ := json.Marshal(pokemon)
fmt.Fprint(w, fmt.Sprintf("%+v", string(pokemonJson)))
}
func handleRequests() {
http.HandleFunc("/", pokemonToJson)
log.Fatal(http.ListenAndServe(":18888", nil))
}
func main() {
handleRequests()
}
Ce que nous faisons ici, c'est "écouter l'accès sur le port 18888, regarder les paramètres de cet accès, obtenir les données Pokemon et renvoyer la valeur de course avec json".
Tout d'abord, la partie en attente au port 18888
//Écoutez le port 18888
http.ListenAndServe(":18888", nil)
Regardez ensuite les paramètres d'accès
//Récupère le paramètre de la clé appelée nom
name := r.FormValue("name")
De plus, obtenez des données Pokemon
//Obtenez Pokemon avec GetPokemonBy dans pokemon2 (détails ci-dessous)
pokemon, err := pokemon2.GetPokemonBy(name)
Enfin, json renvoie la valeur de race
//Convertir la structure en json puis revenir
pokemonJson, _ := json.Marshal(pokemon)
fmt.Fprint(w, fmt.Sprintf("%+v", string(pokemonJson)))
Aller? Que pouvez-vous en manger? Je suis susceptible d'entendre une voix dire "J'imprime sans revenir!", J'ajouterai donc que Fprint est une fonction qui vous permet de spécifier la destination d'écriture, et cette fois j'écris à w (http.ResponseWriter). , On a l'impression qu'il sera retourné en tant que résultat.
pokemon.go
C'est celui qui dit pokemon2.
package pokemon
import (
"errors"
"pokemon/db"
)
type Pokemon struct {
Name string `json:"name"`
HP int `json:"hp"`
Attack int `json:"attack"`
Defense int `json:"defense"`
SpAttack int `json:"sp_attack"`
SpDefense int `json:"sp_defense"`
Speed int `json:"speed"`
}
func GetPokemonBy(name string) (*Pokemon, error) {
pokemonCollection := getPokemonCollection()
for _, pokemon := range pokemonCollection.Pokemons {
if pokemon.Name.Japanese == name {
return getPokemonStruct(pokemon), nil
}
}
return nil, errors.New("")
}
func getPokemonCollection() db.PokemonCollection {
return db.GetPokemonCollection()
}
func getPokemonStruct(pokemon db.PokemonData) *Pokemon {
return &Pokemon{
Name: pokemon.Name.Japanese,
HP: pokemon.Base.HP,
Attack: pokemon.Base.Attack,
Defense: pokemon.Base.Defense,
SpAttack: pokemon.Base.SpAttack,
SpDefense: pokemon.Base.SpDefense,
Speed: pokemon.Base.Speed}
}
//
pokemonCollection := getPokemonCollection()
C'est un joli nom NG. Goland a fait du bon travail ... Je ne trouve pas Pokemon Pour le moment, je vais juste expliquer la fonction appelée GetPokemonBy qui a été appelée depuis main.go
. J'obtiens la base de données via la fonction privée, mais je ne me souviens pas pourquoi.
for _, pokemon := range pokemonCollection.Pokemons {
if pokemon.Name.Japanese == name {
return getPokemonStruct(pokemon), nil
}
}
Si le nom DB Pokemon acquis correspond au nom Pokemon reçu dans le paramètre, ce Pokemon est emballé dans une nouvelle structure et renvoyé.
En gros, le côté API ressemble à ceci.
Vient ensuite le côté qui touche l'API.
main.go
Pour le moment, le code source.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"pokemon_command/input"
"pokemon_command/pokemon"
)
func main() {
url := input.CreateUrl()
resp, _ := http.Get(url)
defer resp.Body.Close()
byteArray, _ := ioutil.ReadAll(resp.Body)
var errCheck map[string]string
json.Unmarshal(byteArray, &errCheck)
if val, ok := errCheck["err"]; ok {
fmt.Println(val)
return
}
pokemonStruct := pokemon.JsonToPokemon(byteArray)
pokemon.PrintPokemon(pokemonStruct)
}
Ceci est une explication du contenu de la fonction principale.
//Les détails de l'entrée seront décrits plus tard
url := input.CreateUrl()
Ici, nous recevons une entrée standard et générons une URL pour accéder à l'API en fonction de celle-ci.
resp, _ := http.Get(url)
defer resp.Body.Close()
Accédez ensuite à l'URL générée et recevez le résultat.
byteArray, _ := ioutil.ReadAll(resp.Body)
Obtient le corps de la réponse reçue.
var errCheck map[string]string
json.Unmarshal(byteArray, &errCheck)
if val, ok := errCheck["err"]; ok {
fmt.Println(val)
return
}
Je fais de la gestion des erreurs ici, mais je ne connais pas la solution optimale. .. ..
//pokemon sera décrit plus tard
pokemonStruct := pokemon.JsonToPokemon(byteArray)
pokemon.PrintPokemon(pokemonStruct)
Le dernier json reçu est stocké dans la structure puis sorti.
main.go
ressemble à ceci.
input.go
package input
import (
"bufio"
"fmt"
"os"
)
func CreateUrl() string {
fmt.Print("Please enter the name of the Pokemon.\n>> ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
return "http://localhost:18888/?name=" + scanner.Text()
}
Ce n'est pas un gros problème ici, il accepte une entrée standard et génère une URL basée sur cette entrée.
fmt.Print("Please enter the name of the Pokemon.\n>> ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
Ces trois lignes affichent le texte qui vous invite à saisir, et l'entrée standard est obtenue par la fonction du package bufio.
return "http://localhost:8081/?name=" + scanner.Text()
L'URL est générée en combinant les chaînes de caractères obtenues. Je veux écrire quelque chose d'un peu mieux.
pokemon.go
package pokemon
import (
"encoding/json"
"fmt"
"log"
)
type Pokemon struct {
Name string `json:"name"`
HP int `json:"hp"`
Attack int `json:"attack"`
Defense int `json:"defense"`
SpAttack int `json:"sp_attack"`
SpDefense int `json:"sp_defense"`
Speed int `json:"speed"`
}
func JsonToPokemon(pokemonJson []byte) *Pokemon {
pokemon := new(Pokemon)
err := json.Unmarshal(pokemonJson, pokemon)
if err != nil {
log.Fatal(err)
}
return pokemon
}
func PrintPokemon(pokemon *Pokemon) {
fmt.Println("Nom: ", pokemon.Name)
fmt.Println("HP : ", pokemon.HP)
fmt.Println("Kogeki: ", pokemon.Attack)
fmt.Println("Bougyo: ", pokemon.Defense)
fmt.Println("Tokukou: ", pokemon.SpAttack)
fmt.Println("Tokubo: ", pokemon.SpDefense)
fmt.Println("Rapidité: ", pokemon.Speed)
}
Encore une fois, ce n'est pas un gros problème, juste une fonction qui emballe le json reçu dans une structure et une fonction qui sort en fonction de cette structure. Je n'ai rien écrit de vraiment important, je vais donc omettre les détails.
C'est un article assez bâclé, mais ← En essayant de faire quelque chose avec GO, je voulais faire quelque chose comme "accepter l'entrée avec l'entrée standard" cette fois, donc pour le moment, je suis content d'avoir pu l'implémenter comme ça. Idéalement, vous devriez créer quelque chose comme la commande pokemon, et l'affichage changera en fonction de l'option. Je veux faire quelque chose comme ça, mais je ferai de mon mieux à un autre moment.
Je voulais accéder à l'API non seulement localement mais à tout moment et n'importe où, alors je me suis inscrit à Sakura VPS et j'ai mis l'API là-bas, alors j'écrirai à ce sujet dans l'article la prochaine fois.
C'est ça!
Recommended Posts