wslでelixir その64

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
Phoenixで、NeosVRコンパイラのapiサーバを作れ。

# 方針
- phx.gen.json使う。
- titleで検索できる様にする。

# 手順
- phx.gen.jsonする。

```
$ mix phx.gen.json Posts Post posts title:string body:text
* creating lib/hello2_web/controllers/post_controller.ex
* creating lib/hello2_web/views/post_view.ex
* creating test/hello2_web/controllers/post_controller_test.exs
* creating lib/hello2/posts/post.ex
* creating priv/repo/migrations/20230925093433_create_posts.exs
* creating lib/hello2/posts.ex
* injecting lib/hello2/posts.ex
* creating test/hello2/posts_test.exs
* injecting test/hello2/posts_test.exs
* creating test/support/fixtures/posts_fixtures.ex
* injecting test/support/fixtures/posts_fixtures.ex

Add the resource to your :api scope in lib/hello2_web/router.ex:

    resources "/posts", PostController, except: [:new, :edit]


Remember to update your repository by running migrations:

    $ mix ecto.migrate
```

- migrateする。

```
$ mix ecto.migrate
warning: the :gettext compiler is no longer required in your mix.exs.

Please find the following line in your mix.exs and remove the :gettext entry:

    compilers: [..., :gettext, ...] ++ Mix.compilers(),

  (gettext 0.23.1) lib/mix/tasks/compile.gettext.ex:5: Mix.Tasks.Compile.Gettext.run/1
  (mix 1.13.4) lib/mix/task.ex:397: anonymous fn/3 in Mix.Task.run_task/3
  (mix 1.13.4) lib/mix/tasks/compile.all.ex:92: Mix.Tasks.Compile.All.run_compiler/2
  (mix 1.13.4) lib/mix/tasks/compile.all.ex:72: Mix.Tasks.Compile.All.compile/4
  (mix 1.13.4) lib/mix/tasks/compile.all.ex:59: Mix.Tasks.Compile.All.with_logger_app/2
  (mix 1.13.4) lib/mix/tasks/compile.all.ex:36: Mix.Tasks.Compile.All.run/1

Compiling 5 files (.ex)
Generated hello2 app

18:36:58.741 [info]  == Running 20230925093433 Hello2.Repo.Migrations.CreatePosts.change/0 forward

18:36:58.750 [info]  create table posts

18:36:58.809 [info]  == Migrated 20230925093433 in 0.0s


```

- route.exを修正。

```
    resources "/posts", PostController, except: [:new, :edit]
	options "/posts", PostController, :options
	options "/posts/:id", PostController, :options
	post "/posts/q", PostController, :select

```
- post_controller.exを修正。


```

  def select(conn, %{"post" => post_params}) do
    post = Posts.get_by(post_params)
    render(conn, "show.json", post: post)
  end


```

- posts.exを修正。


```

  def get_by(%{"body" => body, "title" => title}), do: Repo.get_by(Post, title: title)


```

# plunkerから確認

```
var src0 = document.getElementById('src0');
var src1 = document.getElementById('src1');
var out = document.getElementById('out');
var endpoint = "http://localhost:4000/api/posts";

//get all
function test0() {
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			out.value = xhr.responseText;
		}
		else
		{
			//alert(xhr.readyState);
			//alert(xhr.status);
		}
	};
	xhr.open("GET", endpoint, true);
	xhr.send();
}
//get title
function test1() {
	var endpoint1 = "http://localhost:4000/api/posts/q";
	var src = '{"post": {"body":"a", "title":"Ore"}}';
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			out.value = xhr.responseText;
		}
		else
		{
			//alert(xhr.readyState);
			//alert(xhr.status);
		}
	};
	xhr.open("POST", endpoint1, true);
	xhr.setRequestHeader('Content-Type', 'application/json');
	xhr.send(src);
}
//post ore
function test2() {
	var src = '{"post": {"body":"' + encodeURIComponent(src1.value) + '", "title":"' + src0.value + '"}}';
	//alert(src);
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 201)
		{
			out.value = xhr.responseText;
		}
		else
		{
			alert(xhr.readyState);
			alert(xhr.status);
		}
	};
	xhr.open("POST", endpoint, true);
	xhr.setRequestHeader('Content-Type', 'application/json');
	xhr.send(src);
}



```

# 成果物

https://embed.plnkr.co/plunk/Pbeuk7oncWdsZix1

以上。