2021-02-26 21:40:08 +08:00
---
title: Getting Started
---
2019-12-11 13:42:53 +08:00
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
2021-04-02 09:29:40 +08:00
## Getting Started
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
This guide aims to get started with Apache APISIX, we will configure the service that will route to a public API, secured by an API key.
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
Also, we will take the following `echo` endpoint as an example, it will return parameters we passed.
**Request**
2019-12-11 13:42:53 +08:00
```bash
2021-04-02 09:29:40 +08:00
$ curl --location --request GET "http://httpbin.org/get?foo1=bar1& foo2=bar2"
2019-12-11 13:42:53 +08:00
```
2021-04-02 09:29:40 +08:00
**Response**
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
```json
{
"args": {
"foo1": "bar1",
"foo2": "bar2"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en,zh-CN;q=0.9,zh;q=0.8",
"Cache-Control": "max-age=0",
"Host": "httpbin.org",
"Sec-Ch-Ua": "\"Google Chrome\";v=\"89\", \"Chromium\";v=\"89\", \";Not A Brand\";v=\"99\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-606276ab-2b451d4b36057c186d666351"
},
"origin": "58.152.81.42",
"url": "http://httpbin.org/get?foo1=bar1& foo2=bar2"
}
```
Let's deconstruct the above Request URL.
- Protocol: HTTP
- Port: 80
- Host: `httpbin.org`
- URI/Path: `/get`
2019-12-11 13:42:53 +08:00
- Query Parameters: foo1, foo2
## Prerequisites
2021-04-02 09:29:40 +08:00
> If you have installed the Apache APISIX, feel free and skip to [Step 2](#step-2-create-a-route) please.
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
- This guide uses [Docker ](https://www.docker.com/ ) and [Docker Compose ](https://docs.docker.com/compose/ ) to setup Apache APISIX.
- `curl` : This guide uses the [curl ](https://curl.se/docs/manpage.html ) command for API testing, but you can also use any other tools, e.g [Postman ](https://www.postman.com/ ).
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
I know you're waiting for this moment for a while, let's go!
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
## Step 1: Install Apache APISIX
Thanks to Docker, we could launch the Apache APISIX and enable the [Admin API ](./admin-api.md ) by executing the following commands:
2019-12-11 13:42:53 +08:00
```bash
2020-08-06 10:29:21 +08:00
$ git clone https://github.com/apache/apisix-docker.git
$ cd apisix-docker/example
2019-12-11 13:42:53 +08:00
$ docker-compose -p docker-apisix up -d
```
2021-04-02 09:29:40 +08:00
It will take some time to download all needed files, and this depends on your network, please be patient. Once this step gets done, we could `curl` our Admin API to tell if the Apache APISIX launchs successfully.
2019-12-11 13:42:53 +08:00
```bash
2021-04-02 09:29:40 +08:00
# NOTE: Please curl on the machine which you run above Docker commands.
2020-11-28 19:05:14 +08:00
$ curl "http://127.0.0.1:9080/apisix/admin/services/" -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
2019-12-11 13:42:53 +08:00
```
2021-04-02 09:29:40 +08:00
We expect the following data to be returned:
2019-12-11 13:42:53 +08:00
```json
{
2021-04-02 09:29:40 +08:00
"node": {
"createdIndex": 6,
"modifiedIndex": 6,
"key": "/apisix/services",
"dir": true
},
"action": "get"
2019-12-11 13:42:53 +08:00
}
```
2021-04-02 09:29:40 +08:00
## Step 2: Create a Route
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
Congratulations! You have a running Apache APISIX instance now! Let's create a Route next!
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
### Before we continue
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
Do you know? Apache APISIX provides the powerful [Admin API ](./admin-api.md ) and a [Dashboard ](https://github.com/apache/apisix-dashboard ) for us to use, but we will use Admin API here in this guide. Let's go!
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
We could create one [Route ](./architecture-design/route.md ) and target it to our backend services (We call them [Upstream ](./architecture-design/upstream.md ) usually), when one `Request` reaches Apache APISIX, Apache APISIX will see where this Request should go.
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
Then how does Apache APISIX know this? That's because we have a list of rules configured with Route. Here is a sample Route data:
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
```json
{
"methods": ["GET"],
"host": "example.com",
"uri": "/services/users/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
2019-12-11 13:42:53 +08:00
}
2021-04-02 09:29:40 +08:00
}
}
```
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
This Route means all inbound requests will be forwarded to the `httpbin.org:80` Upstream when they meets **ALL** these rules(matched requests):
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
- Request's HTTP method is `GET` ;
- Request has `Host` Header, and its value is `example.com` ;
- Request's path matches `/services/users/*` , `*` means all subpaths, like `/services/users/getAll?limit=10` .
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
After this Route is created, we could use Apache APISIX's address to access our backend services(Upstream actually):
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
```bash
$ curl -i -X GET "http://{APISIX_BASE_URL}/services/users/getAll?limit=10" -H "Host: example.com"
```
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
This will be forward to `http://httpbin.org:80/getAll?limit=10` by Apache APISIX.
2019-12-11 13:42:53 +08:00
### Create an Upstream
2021-04-02 09:29:40 +08:00
After reading the above section, we know we have to set the `Upstream` for `Route` . Just executing the following command to create one:
2019-12-11 13:42:53 +08:00
```bash
2021-04-02 09:29:40 +08:00
$ curl "http://127.0.0.1:9080/apisix/admin/upstreams/50" -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
2019-12-11 13:42:53 +08:00
{
2021-04-02 09:29:40 +08:00
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
2019-12-11 13:42:53 +08:00
}'
```
2021-04-02 09:29:40 +08:00
We use `roundrobin` as our load balancer mechanism, and set `httpbin.org:80` as our Upstream target(backend server), and its ID is `50` . For more fields, please refer to [Admin API ](./admin-api.md ).
**NOTE:** `Create an Upstream` is not required actually, because we could use [Plugin ](./architecture-design/plugin.md ) to interceptor requests then response directly, but let's assume we need to set at least one `Upstream` in this guide.
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
### Bind Route with Upstream
We just created an Upstream(Reference to our backend services), let's bind one Route with it!
2019-12-11 13:42:53 +08:00
```bash
2021-04-02 09:29:40 +08:00
$ curl "http://127.0.0.1:9080/apisix/admin/routes/5" -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
2019-12-11 13:42:53 +08:00
{
2021-04-02 09:29:40 +08:00
"uri": "/get",
"host": "httpbin.org",
"upstream_id": "50"
2019-12-11 13:42:53 +08:00
}'
```
2021-04-02 09:29:40 +08:00
That's it!
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
### Verification
Congratulations once more! We have created one `Route` and `Upstream` , also we bind them together. Now let's call Apache APISIX to test the `created route` .
2019-12-11 13:42:53 +08:00
```bash
2021-04-02 09:29:40 +08:00
$ curl -i -X GET "http://127.0.0.1:9080/get?foo1=bar1& foo2=bar2" -H "Host: httpbin.org"
2019-12-11 13:42:53 +08:00
```
2021-04-02 09:29:40 +08:00
Wow! It will return data from our `Upstream` (`httpbin.org` actually), it works as expected!
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
## Advanced
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
### Authentication
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
Let's do some interesting things, due to **anyone** could access our public `Route` created in the Step2, we would like only `John` could access it. Let's use [Consumer ](./architecture-design/consumer.md ) and [Plugin ](./architecture-design/plugin.md ) to implement this protection.
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
First, let's create the [consumer ](./architecture-design/consumer.md ) `John` with [key-auth ](./plugins/key-auth.md ) plugin, we need to provide a specified secret key:
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
```bash
$ curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
2019-12-11 13:42:53 +08:00
{
2021-04-02 09:29:40 +08:00
"username": "john",
"plugins": {
"key-auth": {
"key": "superSecretAPIKey"
2019-12-11 13:42:53 +08:00
}
2021-04-02 09:29:40 +08:00
}
2019-12-11 13:42:53 +08:00
}'
```
2021-04-02 09:29:40 +08:00
Next, let's bind our `Consumer(John)` to that `Route` , we only need to **Enable** the [key-auth ](./plugins/key-auth.md ) plugin for that `Route` :
2019-12-11 13:42:53 +08:00
```bash
2021-04-19 08:46:15 +08:00
$ curl http://127.0.0.1:9080/apisix/admin/routes/5 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
2019-12-11 13:42:53 +08:00
{
2021-04-02 09:29:40 +08:00
"uri": "/get",
"host": "httpbin.org",
"plugins": {
"key-auth": {}
},
"upstream_id": 50
2019-12-11 13:42:53 +08:00
}'
```
2021-04-02 09:29:40 +08:00
Ok, when we access the `Route` created in Step2 from now on, an **Unauthorized Error** will occur. Let's see how to access that `Route` :
2019-12-11 13:42:53 +08:00
```bash
2021-04-02 09:29:40 +08:00
$ curl -i -X GET http://127.0.0.1:9080/get -H "Host: httpbin.org" -H 'apikey: superSecretAPIKey'
2019-12-11 13:42:53 +08:00
```
2021-04-02 09:29:40 +08:00
Ya, just added an `Header` called `apikey` with correct key! It's so easy to protect any `Routes` , right?
### Prefix in Route
2020-03-13 08:34:02 +08:00
Now lets say you want to add a prefix (eg: samplePrefix) to the route and do not want to use the `host` header then you can use
2021-03-29 15:14:13 +08:00
the proxy-rewrite plugin to do it.
2020-03-13 08:34:02 +08:00
```bash
2021-04-19 08:46:15 +08:00
$ curl http://127.0.0.1:9080/apisix/admin/routes/5 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
2020-03-13 08:34:02 +08:00
{
2021-04-02 09:29:40 +08:00
"uri": "/samplePrefix/get",
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/samplePrefix/get(.*)", "/get$1"]
2020-03-13 08:34:02 +08:00
},
2021-04-02 09:29:40 +08:00
"key-auth": {}
},
"upstream_id": 50
2020-03-13 08:34:02 +08:00
}'
```
Now you can invoke the route with the following command:
```bash
2021-04-02 09:29:40 +08:00
$ curl -i -X GET 'http://127.0.0.1:9080/samplePrefix/get?param1=foo& param2=bar' -H 'apikey: superSecretAPIKey'
2020-03-13 08:34:02 +08:00
```
2021-04-02 09:29:40 +08:00
### APISIX Dashboard
2020-03-18 08:47:55 +08:00
2021-04-21 08:56:47 +08:00
Apache APISIX provides a [Dashboard ](https://github.com/apache/apisix-dashboard ) to let us operate Apache APISIX more easier.
2020-03-18 08:47:55 +08:00
2021-04-02 09:29:40 +08:00
![Dashboard ](../../assets/images/dashboard.jpeg )
2020-03-18 08:47:55 +08:00
2019-12-11 13:42:53 +08:00
### Troubleshooting
2021-04-02 09:29:40 +08:00
- Make sure all required ports (**9080/9443/2379 by default**) are not being used by other systems/processes.
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
The following command will kill the process which is listening on a specific port (in unix based systems).
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
```bash
$ sudo fuser -k 9443/tcp
```
- If the docker container is restarting/failing continuously, just access to the container and observe the logs to find out what happened.
2019-12-11 13:42:53 +08:00
2021-04-02 09:29:40 +08:00
```bash
$ docker logs -f --tail container_id
```