Skip to content

Commit 3deca17

Browse files
authored
Merge pull request #2 from niden/master
v1.1
2 parents 9f25cec + 947e0d1 commit 3deca17

File tree

112 files changed

+5709
-1062
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+5709
-1062
lines changed

README.md

Lines changed: 96 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
# phalcon-api
22
Sample API using Phalcon
33

4-
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/niden/phalcon-api/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/niden/phalcon-api/?branch=master)
5-
[![Code Coverage](https://scrutinizer-ci.com/g/niden/phalcon-api/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/niden/phalcon-api/?branch=master)
6-
[![Build Status](https://scrutinizer-ci.com/g/niden/phalcon-api/badges/build.png?b=master)](https://scrutinizer-ci.com/g/niden/phalcon-api/build-status/master)
4+
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/phalcon/phalcon-api/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/phalcon/phalcon-api/?branch=master)
5+
[![Code Coverage](https://scrutinizer-ci.com/g/phalcon/phalcon-api/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/phalcon/phalcon-api/?branch=master)
6+
[![Build Status](https://scrutinizer-ci.com/g/phalcon/phalcon-api/badges/build.png?b=master)](https://scrutinizer-ci.com/g/phalcon/phalcon-api/build-status/master)
77

88

9-
Implementation of an API application using the Phalcon Framework (https://phalconphp.com)
9+
Implementation of an API application using the Phalcon Framework [https://phalconphp.com](https://phalconphp.com)
1010

1111
### Installation
1212
- Clone the project
1313
- In the project folder run `nanobox run php-server`
1414
- Hit the IP address with postman
1515

16-
This requires [nanobox](https://nanobox.io) to be present in your system. Visit their site for installation instructions.
16+
**NOTE** This requires [nanobox](https://nanobox.io) to be present in your system. Visit their site for installation instructions.
1717

1818
### Features
1919
##### JWT Tokens
@@ -24,65 +24,106 @@ As part of the security of the API, [JWT](https://jwt.io) are used. JSON Web Tok
2424
- Stop execution as early as possible when an error occurs
2525
- Execution
2626
- NotFound - 404 when the resource requested is not found
27-
- Payload - Check the posted JSON string if it is correct
2827
- Authentication - After a `/login` checks the `Authentication` header
2928
- TokenUser - When a token is supplied, check if it corresponds to a user in the database
3029
- TokenVerification - When a token is supplied, check if it is correctly signed
3130
- TokenValidation - When a token is supplied, check if it is valid (`issuedAt`, `notBefore`, `expires`)
3231

32+
##### JSONAPI
33+
This implementation follows the [JSON API](https://jsonapi.org) standard. All responses are formatted according to the standard, which offers a uniformed way of presenting data, simple or compound documents, includes (related data), sparse fieldsets, sorting, patination and filtering.
34+
3335
### Usage
3436

3537
#### Requests
36-
All requests to the API have be submitted using `POST`. All requests must send a JSON string with one root element `data`. Data needed for the request must be under the `data` element
37-
38-
The endpoints are:
39-
40-
`/login`
41-
42-
| Method | Payload |
43-
|--------|--------------------------------------------------------|
44-
| `POST` | `{"data": {"username": "niden", "password": "12345"}}` |
38+
The routes available are:
39+
40+
| Method | Route | Parameters | Action |
41+
|--------|--------------------|------------------------------------|----------------------------------------------------------|
42+
| `POST` | `login` | `username`, `password` | Login - get Token |
43+
| `POST` | `companies` | `name`, `address`, `city`, `phone` | Add a company record in the database |
44+
| `GET` | `companies` | | Get companies. Empty resultset if no data present |
45+
| `GET` | `companies` | Numeric Id | Get company by id. 404 if record does not exist |
46+
| `GET` | `individuals` | | Get individuals. Empty resultset if no data present |
47+
| `GET` | `individuals` | Numeric Id | Get individual by id. 404 if record does not exist |
48+
| `GET` | `individual-types` | | Get individual types. Empty resultset if no data present |
49+
| `GET` | `individual-types` | Numeric Id | Get individual type by id. 404 if record does not exist |
50+
| `GET` | `products` | | Get products. Empty resultset if no data present |
51+
| `GET` | `products` | Numeric Id | Get product by id. 404 if record does not exist |
52+
| `GET` | `product-types` | | Get product types. Empty resultset if no data present |
53+
| `GET` | `product-types` | Numeric Id | Get product type by id. 404 if record does not exist |
54+
| `GET` | `users` | | Get users. Empty resultset if no data present |
55+
| `GET` | `users` | Numeric Id | Get user by id. 404 if record does not exist |
56+
57+
#### Relationships
58+
59+
`/companies/<number>/individuals`
60+
`/companies/<number>/products`
61+
`/companies/<number>/individuals,products`
62+
63+
`/companies/<number>/relationships/individuals`
64+
`/companies/<number>/relationships/products`
65+
`/companies/<number>/relationships/individuals,products`
66+
67+
`individuals/<number>/companies`
68+
`individuals/<number>/individual-types`
69+
`individuals/<number>/companies,individual-types`
70+
71+
`individuals/<number>/relationships/companies`
72+
`individuals/<number>/relationships/individual-types`
73+
`individuals/<number>/relationships/companies,individual-types`
74+
75+
`individual-types/<number>/individuals`
76+
`individual-types/<number>/relationships/individuals`
77+
78+
`products/<number>/companies`
79+
`products/<number>/product-types`
80+
`products/<number>/companies,product-types`
81+
82+
`products/<number>/relationships/companies`
83+
`products/<number>/relationships/product-types`
84+
`products/<number>/relationships/companies,product-types`
85+
86+
`product-types/<number>/products`
87+
`product-types/<number>/relationships/products`
88+
4589

46-
`/user/get`
4790

48-
| Method | Payload |
49-
|--------|---------------------------------------------------------|
50-
| `POST` | `{"data": {"userId": 1}}` | with Bearer Authentication` |
51-
52-
`/usesr/get`
53-
54-
| Method | Payload |
55-
|--------|---------|
56-
| `POST` | Empty |
57-
5891
#### Responses
5992
##### Structure
93+
**Top Elements**
94+
- `jsonapi` Contains the `version` of the API as a sub element
95+
- `data` Data returned. Is not present if the `errors` is present
96+
- `errors` Collection of errors that occurred in this request. Is not present if the `data` is present
97+
- `meta` Contains `timestamp` and `hash` of the `json_encode($data)` or `json_encode($errors)`
98+
99+
After a `GET` the API will always return a collection of records, even if there is only one returned. If no data is found, an empty resultset will be returned.
100+
101+
Each endpoint returns records that follow this structure:
60102
```json
61103
{
62-
"jsonapi": {
63-
"version": "1.0" // Version of the API
64-
},
65-
"data": [
66-
// Payload returned if successful reply (not present if there is an error)
67-
],
68-
"errors": [
69-
"Error 1", // Collection of errors
70-
"Error 2"
71-
},
72-
"meta": {
73-
"timestamp": "2018-06-08T15:04:34+00:00", // Timestamp of the response
74-
"hash": "e6d4d57162ae0f220c8649ae50a2b79fd1cb2c60" // Hash of the timestamp and payload (`data` if success, `error` if failure)
104+
"id": 1051,
105+
"type": "users",
106+
"attributes": {
107+
"status": 1,
108+
"username": "niden",
109+
"issuer": "https:\/\/niden.net",
110+
"tokenPassword": "11110000",
111+
"tokenId": "11001100"
75112
}
76113
}
77114
```
78-
##### 404
115+
116+
The record always has `id` and `type` present at the top level. `id` is the unique id of the record in the database. `type` is a string representation of what the object is. In the above example it is a `users` record. Additional data from each record are under the `attributes` node.
117+
118+
#### Samples
119+
**404**
79120
```json
80121
{
81122
"jsonapi": {
82123
"version": "1.0"
83124
},
84125
"errors": {
85-
"404 Not Found"
126+
"404 not found"
86127
},
87128
"meta": {
88129
"timestamp": "2018-06-08T15:04:34+00:00",
@@ -91,14 +132,16 @@ The endpoints are:
91132
}
92133
```
93134

94-
##### Error
135+
**Error**
136+
95137
```json
96138
{
97139
"jsonapi": {
98140
"version": "1.0"
99141
},
100142
"errors": {
101-
"Description of the error"
143+
"Description of the error no 1",
144+
"Description of the error no 2"
102145
},
103146
"meta": {
104147
"timestamp": "2018-06-08T15:04:34+00:00",
@@ -107,92 +150,29 @@ The endpoints are:
107150
}
108151
```
109152

110-
##### Success
153+
##### Success
111154
```json
112155
{
113156
"jsonapi": {
114157
"version": "1.0"
115158
},
116159
"data": [
117-
// Data returned
118160
],
119161
"meta": {
120162
"timestamp": "2018-06-08T15:04:34+00:00",
121163
"hash": "e6d4d57162ae0f220c8649ae50a2b79fd1cb2c60"
122164
}
123165
}
124166
```
125-
126-
`/login`
127-
```json
128-
{
129-
"jsonapi": {
130-
"version": "1.0"
131-
},
132-
"data": {
133-
"token": "ab.cd.ef"
134-
},
135-
"meta": {
136-
"timestamp": "2018-06-08T15:04:34+00:00",
137-
"hash": "e6d4d57162ae0f220c8649ae50a2b79fd1cb2c60"
138-
}
139-
}
140-
```
141167

142-
`/user/get`
143-
```json
144-
{
145-
"jsonapi": {
146-
"version": "1.0"
147-
},
148-
"data": [
149-
{
150-
"id": 1244,
151-
"status": 1,
152-
"username": "phalcon",
153-
"issuer": "https:\/\/phalconphp.com",
154-
"tokenPassword": "00001111",
155-
"tokenId": "99009900"
156-
}
157-
],
158-
"meta": {
159-
"timestamp": "2018-06-08T17:05:14+00:00",
160-
"hash": "344d9766003e14409ab08df863d37d1ef44e5b60"
161-
}
162-
}
163-
```
164-
`/users/get`
165-
```json
166-
{
167-
"jsonapi": {
168-
"version": "1.0"
169-
},
170-
"data": [
171-
{
172-
"id": 1051,
173-
"status": 1,
174-
"username": "niden",
175-
"issuer": "https:\/\/niden.net",
176-
"tokenPassword": "11110000",
177-
"tokenId": "11001100"
178-
},
179-
{
180-
"id": 1244,
181-
"status": 1,
182-
"username": "phalcon",
183-
"issuer": "https:\/\/phalconphp.com",
184-
"tokenPassword": "00001111",
185-
"tokenId": "99009900"
186-
}
187-
],
188-
"meta": {
189-
"timestamp": "2018-06-08T15:07:35+00:00",
190-
"hash": "6219ae83afaebc08da4250c4fd23ea1b4843d"
191-
}
192-
}
193-
```
194-
168+
For more information regarding responses, please check [JSON API](https://jsonapi.org)
169+
195170
### TODO
196-
- Remove `/login` endpoint. Leave the generation of the JWT to the consumer (maybe)
197-
- Perhaps add a new claim to the token tied to the device? `setClaim('deviceId', 'Web-Server')`. This will allow the client application to invalidate access to a device that has already been logged in.
171+
- ~~Work on companies GET~~
172+
- ~~Work on relationships and data returned~~
198173
- Write examples of code to send to the client
174+
- Create docs endpoint
175+
- Work on pagination
176+
- Work on filters
177+
- Work on sorting
178+
- Perhaps add a new claim to the token tied to the device? `setClaim('deviceId', 'Web-Server')`. This will allow the client application to invalidate access to a device that has already been logged in.

api/config/providers.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Enabled providers. Order does matter
55
*/
66

7+
use Niden\Providers\CacheDataProvider;
78
use Niden\Providers\ConfigProvider;
89
use Niden\Providers\DatabaseProvider;
910
use Niden\Providers\ErrorHandlerProvider;
@@ -22,4 +23,5 @@
2223
RequestProvider::class,
2324
ResponseProvider::class,
2425
RouterProvider::class,
26+
CacheDataProvider::class,
2527
];

0 commit comments

Comments
 (0)